Search code examples
iosswiftxcoderootviewcontrolleruiscenedelegate

when need to switch the rootViewController


I've been working on a Swift project and I have two view controllers, the login view controller & the home view controller. When a user launches the app, I want to display the login view controller if the user is not logged in, on the other hand, if the user is logged in, I want to display the home view controller.

So the flow is gonna be something like this.

When the user is not logged in, display

  1. LoginViewController
  2. HomeViewController

When the user is already logged in, display

  1. HomeViewController

In the scene delegate, I've written

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    guard let scene = (scene as? UIWindowScene) else { return }

    window = UIWindow(frame: scene.coordinateSpace.bounds)
    window?.windowScene = scene
    window?.rootViewController = HomeViewController() or LoginViewController() depending on the user's login status
    window?.makeKeyAndVisible()
}

I was wondering if I should apply the HomeViewController as a rootviewcontroller regardless of the user's login status (and maybe present loginVC on the homeVC when the user is not logged in), or I should switch the view controller depending on the user's login status.

So, in this case, what is the point of switching rootviewcontroller? and why it is (or isn't important) to switch the root view controller?

Is there anything I should consider when I apply view controller to the root viewcontroller property?


Solution

  • Hi all i have one idea for set a RootViewController in SceneDelegate. First we need to create the method setViewController and variable currentScene in SceneDelegate class kindly feel free to refer the code below. Two different viewcontroller as per your example HomeViewController, LoginViewController

    import UIKit
    
    class SceneDelegate: UIResponder, UIWindowSceneDelegate {
      
      var window: UIWindow?
      var currentScene: UIScene?
      
      func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let _ = (scene as? UIWindowScene) else { return }
        currentScene = scene
        if UserDefaults.standard.bool(forKey: "isLoggedIn") == true{
          self.setRootViewController(LoginViewController())
        }else{
          self.setRootViewController(HomeViewController())
        }
      }
      
      func setRootViewController(_ viewController: UIViewController){
        
        guard let scene = (currentScene as? UIWindowScene) else { return }
        
        window = UIWindow(frame: scene.coordinateSpace.bounds)
        window?.windowScene = scene
        window?.rootViewController = viewController
        window?.makeKeyAndVisible()
        
      }
      
    }
    
    class ButtonViewController: UIViewController {
      
      lazy var button: UIButton! = {
        
        let button = UIButton()
        button.translatesAutoresizingMaskIntoConstraints = false
        button.backgroundColor = .darkGray
        button.setTitleColor(.white, for: .normal)
        button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
        button.tag = 1
        button.setTitle("Tap", for: .normal)
        return button
        
      }()
      
      
      override func loadView() {
        super.loadView()
        self.view.backgroundColor = .white
        
        setConstraint()
      }
      
      override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
      }
      
      func setConstraint(){
        
        self.view.addSubview(self.button)
        
        NSLayoutConstraint.activate([
          
          self.button.heightAnchor.constraint(equalToConstant: 60),
          self.button.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width * 0.66),
          self.button.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
          self.button.centerYAnchor.constraint(equalTo: self.view.centerYAnchor),
          
        ])
        
      }
      
      @objc func buttonAction(){  }
      
    }
    
    class HomeViewController: ButtonViewController{
      
      override func loadView() {
        super.loadView()
        self.view.backgroundColor = .red
        self.button.setTitle(String(describing: HomeViewController.self), for: .normal)
      }
      
      override func buttonAction() {
        let sceneDelegate = UIApplication.shared.connectedScenes.first?.delegate as! SceneDelegate
        sceneDelegate.setRootViewController(LoginViewController())
      }
      
    }
    
    
    class LoginViewController: ButtonViewController{
      
      override func loadView() {
        super.loadView()
        self.view.backgroundColor = .green
        self.button.setTitle(String(describing: LoginViewController.self), for: .normal)
      }
      
      override func buttonAction() {
        let sceneDelegate = UIApplication.shared.connectedScenes.first?.delegate as! SceneDelegate
        sceneDelegate.setRootViewController(HomeViewController())
      }
      
    }
    

    If click the button view controller can be change as rootViewController. Output:

    enter image description here