在 iOS 应用程序启动时有条件地切换根视图控制器的最佳方式

Best way to conditionally switch root view controller at iOS app start-up

这里是新 iOS 开发人员。我正在做一个项目,要求用户在第一次打开应用程序时登录。从那时起,我希望应用程序直接打开到应用程序的主要流程(在我的例子中是一个标签栏控制器)。在做了一些研究之后,我发现了实现此功能的两种主要方法:

1) 在应用程序委托中有条件地设置应用程序 window 的根视图控制器。例如:

    if userLoggedIn {
        let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
        let tabBarController: UITabBarController = storyboard.instantiateViewControllerWithIdentifier("TabBarController") as! UITabBarController
        self.window?.makeKeyAndVisible()
        self.window?.rootViewController = tabBarController
    } else {
        let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
        let logInViewController: LogInViewController = storyboard.instantiateViewControllerWithIdentifier("LogInViewController") as! LogInViewController
        self.window?.makeKeyAndVisible()
        self.window?.rootViewController = logInViewController
    }

2) 使用导航控制器作为应用的根视图控制器,并在应用委托中有条件地设置由导航控制器管理的视图控制器。例如:

    if userLoggedIn {
        let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
        let tabBarController: UITabBarController = storyboard.instantiateViewControllerWithIdentifier("TabBarController") as! UITabBarController

        let navigationController = self.window?.rootViewController as! UINavigationController
        navigationController.navigationBarHidden = true
        navigationController.setViewControllers([tabBarController], animated: true)
    } else {
        let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
        let tabBarController: ViewController = storyboard.instantiateViewControllerWithIdentifier("LoginViewController") as! ViewController

        let navigationController = self.window?.rootViewController as! UINavigationController
        navigationController.navigationBarHidden = true
        navigationController.setViewControllers([tabBarController], animated: true)
    }

如果我选择第二个选项,我可以在完成用户登录后轻松转换到应用程序的主流程(比如说标签栏控制器)。在 LogInViewController 的适当位置,我可以说:

    // Transition to tab bar controller
    let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
    let tabBarController: UITabBarController = storyboard.instantiateViewControllerWithIdentifier("TabBarController") as! UITabBarController

    self.navigationController?.setViewControllers([tabBarController], animated: true)

很简单。

关于第一种方法,我不确定用户登录后如何过渡到应用程序的主要内容。

我在这里寻找的是 "best" 处理登录流程的方法。我列出了两种方法,但也许还有另一种更好的方法。另外,如果 "best" 方法是我列出的第一个方法,那么在我完成用户登录后如何才能到达我的选项卡栏控制器?谢谢!

这两个都是不错的选择。我做过的一件效果很好的事情是将自定义容器视图控制器实现为我的应用程序的根(这可能是我的主视图控制器的子类,如选项卡栏控制器或导航控制器)。

在这个容器视图控制器中,我可以放置代码来根据用户的登录状态显示和关闭登录视图控制器。注意:您还可以在此处使用临时全屏视图在登录屏幕 shown/dismissed 时隐藏应用的主要内容 - 这是获得非常流畅的应用启动过渡的简单方法。

我特别喜欢这种方法,因为应用程序的其余部分不需要担心细节。您的容器可以像普通的选项卡栏控制器或导航控制器一样工作,但在下面,您可以将所有登录 UI 逻辑封装在一个地方。