-->

Presenting Login View Controller Before the UITabB

2019-08-26 06:59发布

问题:

I want to provide a log on view controller so my users can authenticate prior to being presented the tab bar controller. In the code displayed below, I get the error "Could not cast value of type 'LogInViewController' to 'UITabBarController'. Apple documentation listed:

When deploying a tab bar interface, you must install this view as the root of your window. Unlike other view controllers, a tab bar interface should never be installed as a child of another view controller.

I am stumped and my implementation is complicated when I am propagating core data across the 5 view controllers (e.g. controller1.coreDataStack = coreDataStack, declared as a property in the AppDelegate class) that is part of the tab bar controller. Can I get some help on how should I transition the user from the log in screen to one of the tabbed view controllers? Any input would be appreciated.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    // Login View Controller
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let loginVC = storyboard.instantiateViewController(withIdentifier: "loginVC") as! LogInViewController
    self.window?.rootViewController = loginVC

    // TabBar Controller
    let tabController = window!.rootViewController as! UITabBarController
    if let tabViewControllers = tabController.viewControllers {
        // First tab (only one so far...)
        let navController = tabViewControllers[0] as! UINavigationController
        let controller1 = navController.viewControllers.first as! FirstViewController
        controller1.coreDataStack = coreDataStack
    }
}

回答1:

You got error because trying to force unwrap LogInViewController to UITabBarController.

For your design flow store loginStatus of user in database an check condition on this before setting the window.rootViewController, if user is logged-in then show tabController, otherwise show LogInViewController.

        let userLogined = GET LOGIN STATUS FROM DATABSE
        if userLogined{
            // Initiate Tabbar Controller object
            let tabController = INITIATE_TABBAR_CONTROLLER
            let tabViewControllers = tabController.viewControllers
            // First tab (only one so far...)
            let navController = tabViewControllers[0] as! UINavigationController
            let controller1 = navController.viewControllers.first as! FirstViewController
            controller1.coreDataStack = coreDataStack
            self.window?.rootViewController = tabController

        }else{
            // Login View Controller
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            let loginVC = storyboard.instantiateViewController(withIdentifier: "loginVC") as! LogInViewController
            self.window?.rootViewController = loginVC
        }


回答2:

As an alternative method, how about always setting the rootViewController to the tabbed bar controller. Then if the user is logged out, modally present the login view controller from the tabbed bar controller. Once the user has successfully logged in, dismiss the login view controller. I've used this method many times on many apps.