Search code examples
swiftuinavigationcontroller

How to change rootViewController in swift?


I am working on an application in which there is no login logout feature. When user opens the application he sees main screen. Now there is an option in setting page named as Pin Lock application. When user select this option a PinScreen comes(like OTP Screen) then user sets the Pin. After that When user closes the application the Pin lock screen comes first asking user to enter pin. So how can i do that?

if UserDefaults.standard.bool(forKey: "LoggedIn") == false {

        let story = UIStoryboard(name: "Main", bundle:nil)
        let vc = story.instantiateViewController(withIdentifier: "EnterPin") as! UINavigationController
        UIApplication.shared.windows.first?.rootViewController = vc
        UIApplication.shared.windows.first?.makeKeyAndVisible()

        let enterPinViewController = self.storyboard.instantiateViewController(identifier: "EnterPinViewController") as! EnterPinViewController
        self.navigationController.present(enterPinViewController, animated: true, completion: nil)

    } else if UserDefaults.standard.bool(forKey: "LoggedIn") == true {

        let story = UIStoryboard(name: "Main", bundle:nil)
        let vc = story.instantiateViewController(withIdentifier: "MainController") as! UINavigationController
        UIApplication.shared.windows.first?.rootViewController = vc
        UIApplication.shared.windows.first?.makeKeyAndVisible()

        let mainViewController = self.storyboard.instantiateViewController(identifier: "ViewController") as! ViewController
        self.navigationController.present(mainViewController, animated: true, completion: nil)


    }

Currently i am setting UserDefaults value as true and false and saving Pin in UserDefaults itself. I have tried changing rootViewController but nothing happening means every time main screen is coming instead of Pin Screen.


Solution

  • First you need to get the Window from SceneDelegate and use that window for rootViewController.

    Suggestion: Whenever we are using rootViewController then no need to do present and push thing it will automatically set as a main home viewcontroller(Intial viewController)

     let window = (UIApplication.shared.connectedScenes.first!.delegate as! SceneDelegate).window
                let storyboard = UIStoryboard(name: "Main", bundle:nil)
            if UserDefaults.standard.bool(forKey: "LoggedIn") == false {
                let vc =storyboard.instantiateViewController(withIdentifier: "EnterPin") as! UINavigationController
                window?.rootViewController = vc
                window?.makeKeyAndVisible()
            } else if UserDefaults.standard.bool(forKey: "LoggedIn") == true {
                let vc =storyboard.instantiateViewController(withIdentifier: "MainController") as! UINavigationController
                window?.rootViewController = vc
                window?.makeKeyAndVisible()
            }
    

    I suggest you do all this things in SceneDelegate file

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
            guard let scene = (scene as? UIWindowScene) else { return }
            self.window = UIWindow(windowScene: scene)
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            if UserDefaults.standard.bool(forKey: "LoggedIn") == false {
                let vc = storyboard.instantiateViewController(withIdentifier: "EnterPin") as! UINavigationController
                self.window?.rootViewController = vc
                self.window?.makeKeyAndVisible()
            } else if UserDefaults.standard.bool(forKey: "LoggedIn") == true {
                let vc = storyboard.instantiateViewController(withIdentifier: "MainController") as! UINavigationController
                self.window?.rootViewController = vc
                self.window?.makeKeyAndVisible()
            }
        }
    

    I Hope it is helpful for you!