0

I am developing the iOS app. and it has some design restrictions by the client. So it looks like I have to use navigation controller and the tab controller simultaneously on different number of Viewcontrollers.

I can categories my views into 2 category.

  1. SignUp/Login views (this is entry point at first start of app)
  2. MainView -> This become entry point once the user is login

Now Category 1 is using NavigationView Controllers. where as Category2 is using Tab bar controllers.

What I want case 1: I want when the user install my app, he is taken to Login view which has Navigation View. Now if he already has no account he will go to "Create new account" this is the 2nd scene of the Navigation view. Now on successful creation of account, he needs to close all other navigation view controllers and need to jump to MainView which will be Tabbar view controller.

case 2: suppose user close my app after getting login, when he open it up again, now the entery point will be Mainview which has Tab bar view controller. Now I know I need to do it in App delegate method but how?

I am doing this way,and it looks like working. But I am not getting bottom tab. Why is it so?

class ViewSwitcher {

    static func updateRootViewController() {

        let status = UserDefaults.standard.bool(forKey: KeyConstants.IS_USER_LOGGEDIN)
        var rootViewController : UIViewController?

        #if DEBUG
            print(status)
        #endif

        if (status == true) {
            let mainStoryBoard = UIStoryboard(name: "Main", bundle: nil)
            let mainTabBarController = mainStoryBoard.instantiateViewController(withIdentifier: "idTab1VC") as! Tab1VC
            rootViewController = mainTabBarController
        } else {
            let mainStoryBoard = UIStoryboard(name: "Main", bundle: nil)
            let signInViewController = mainStoryBoard.instantiateViewController(withIdentifier: "idLoginVC") as! LoginVC
            rootViewController = signInViewController
        }

        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        appDelegate.window?.rootViewController = rootViewController

    }

}

Any Idea how to do these cases? How to navigate programmatically by closing all the view controllers trees?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Android teem
  • 780
  • 2
  • 13
  • 36

4 Answers4

1

The same process I have been using for my app.

Use this code to change the rootViewController in Case2

var window: UIWindow?
var tabBarController : UITabBarController?

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

        // Tabbar controller
        let storyBoard = UIStoryboard.init(name: "Main", bundle: Bundle.main)
        let tab1 = UINavigationController.init(rootViewController: storyBoard.instantiateViewController(withIdentifier: "tab1"))
        tab1 = UITabBarItem.init(title: "Title 1", image: UIImage(named : "Image.png") , tag: 0)
        let tab2 = UINavigationController.init(rootViewController: storyBoard.instantiateViewController(withIdentifier: "tab2"))
        tab2 = UITabBarItem.init(title: "Title 2", image: UIImage(named : "Image.png") , tag: 1)

        // Navigation controller or Login view controller
        let nav1 = UINavigationController.init(rootViewController: storyBoard.instantiateViewController(withIdentifier: "nav1"))

        tabBarController = UITabBarController.init()
        tabBarController?.delegate = self
        tabBarController?.selectedIndex = 0
        tabBarController?.viewControllers = [tab1,tab2]

       // The Bool value which you have to set as True after a user logged in 
        if UserDefaults.standard.bool(forKey: "LoggedIn"){
            print("Tabbar")
            self.window?.rootViewController = self.tabBarController
        }else{
            print("Navigation")
            self.window?.rootViewController = nav1
        }

        return true
    }

Before or After that, you have to write the same code where a user clicked on login in your loginViewController, in your case it is Case1

     func loginClicked(){
         UserDefaults.standard.set(true, forKey: "LoggedIn")
         DispatchQueue.main.async {
            let appdelegate = UIApplication.shared.delegate as! AppDelegate
            // Same as above code and replace self with appDelegate without if condition and at last
            appdelegate.window?.rootViewController = appdelegate.tabBarController
         }
      }

And after user logged out

         DispatchQueue.main.async {
                    UserDefaults.standard.set(false, forKey: "LoggedIn")
                    let appdelegate = UIApplication.shared.delegate as! AppDelegate
                    let story = UIStoryboard.init(name: "Main", bundle: Bundle.main)
                    let nav1 = UINavigationController.init(rootViewController: storyBoard.instantiateViewController(withIdentifier: "nav1"))
                    appdelegate.window?.rootViewController = companyNavigation
}
Himanth
  • 2,381
  • 3
  • 28
  • 41
0

Use below code in app delegate didFinishWithLaunchingOptions , for main view directly.. here uid means stored value whether to check user is Active or Not.

        let storyboard = UIStoryboard(name: "Main", bundle: nil)
                   if let user_id = UserDefaults.standard.value(forKey: "uid")
                   {
                       let homeViewController = storyboard.instantiateViewController(withIdentifier: "HomeTabBarCtrlr") as! UITabBarController

                        let nav = UINavigationController(rootViewController: homeViewController)
                       self.window!.rootViewController = nav
                   }else{

SignUp/Login views }

Sandeep Baddula
  • 181
  • 1
  • 9
0

Step by step approach to this would be:

  1. Check if user is logged in or not. For this use UserDefaults.
  2. If user not logged in, set LoginVC as rootVC.
  3. On Login save a key in UserDefault to signify user logged in.
  4. Next time when user opens the app check for key and if user logged in, set TabBarVC as rootViewController.
  5. At Logout, clear the key.

Sample Code for the above will be:

AppDelegate.swift

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

        //Check for user login and set rootViewController.
        if UserDefaults.standard.bool(forKey: "login"){
            self.window?.rootViewController = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController()
        }
        else{
            self.window?.rootViewController = UIStoryboard(name: "Login", bundle: nil).instantiateInitialViewController()
        }
        return true
    }

At Login Success

    func loginUser(){
       ...
       if userLoginSuccess{
        UserDefaults.standard.set(true, forKey: "login")
    }
}

At Logout

UserDefaults.standard.set(false, forKey: "login")
udbhateja
  • 948
  • 6
  • 21
0

As like you know that you want to do it in Appdelgate.

When user login successfully you have to store a flag in userdefault. In app delegate you have to check that if this flag is set or not.If set then create a navigation view controller with your initial view controller call moveToLoginWindow(). or if not then create tab bar view controller call movetoTabBarController().

func moveToLoginWindow() -> Void {

        if let rootController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "LoginVC") as? LoginVC{
            let navigationController = UINavigationController.init(rootViewController: rootController)
            self.window?.rootViewController = navigationController
            self.window?.makeKeyAndVisible()
        }
    }


func movetoTabBarController() -> Void {

    let nav2 = UINavigationController()

    let second = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "secondViewController") as? SecureNotesVC
    nav2.viewControllers = [second!]
    nav2.tabBarItem =  UITabBarItem.init(title: "Titel 2", image: UIImage.init(named: "2.png"), selectedImage: UIImage.init(named: "2_sel.png"))


    let nav3 = UINavigationController()

    let third =  UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "thirdviewController") as? FormFillsVC
    nav3.viewControllers = [third!]
    nav3.tabBarItem = UITabBarItem.init(title: "Titel 2", image: UIImage.init(named: "3.png"), selectedImage: UIImage.init(named: "3_sel.png"))


    let nav4 = UINavigationController()

    let fourth = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "fourthviewContoller") as? SettingsVC
    nav4.viewControllers = [fourth!]
    nav4.tabBarItem =  UITabBarItem.init(title: "4", image: UIImage.init(named: "4.png"), selectedImage: UIImage.init(named: "4_sel.png"))




    if #available(iOS 11.0, *) {
        nav2.navigationBar.prefersLargeTitles = true
        nav3.navigationBar.prefersLargeTitles = true
        nav4.navigationBar.prefersLargeTitles = true
    }

    let tabBarController = UITabBarController()
    tabBarController.viewControllers = [ nav2,nav3, nav4,nav5]
   self.window!.rootViewController = tabBarController;






 }
Yatendra
  • 1,310
  • 1
  • 18
  • 31