Set rootViewController iOS 13

11,944

Solution 1

This is because AppDelegate doesn't have window property anymore. Now you must use SceneDelegate's scene(_:willConnectTo:options:) method to change root view controller. Like shown in this example:

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

        // Instantiate UIWindow with scene
        let window = UIWindow(windowScene: scene)
        // Assign window to SceneDelegate window property
        self.window = window
        // Set initial view controller from Main storyboard as root view controller of UIWindow
        self.window?.rootViewController = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController()
        // Present window to screen
        self.window?.makeKeyAndVisible()
    }

Solution 2

It is available in SceneDelegate.swift file in your project

It will have delegate method :

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)

Example

func scene(_ scene: UIScene, willConnectTo session: UISceneSession,
 options connectionOptions: UIScene.ConnectionOptions) {


if let windowScene = scene as? UIWindowScene {

    self.window = UIWindow(windowScene: windowScene) 

    let initialViewController = 
        storyboard.instantiateViewController(withIdentifier: "FirstViewController")            
        self.window!.rootViewController = initialViewController
        self.window!.makeKeyAndVisible()
    }

}

Solution 3

In viewDidAppear you can set root:-

  override func viewDidAppear(_ animated: Bool) {
            print(self.view.window)
            let vc = self.storyboard?.instantiateViewController(identifier: "SecondViewController") as? SecondViewController
            self.view.window?.rootViewController = vc
        }
Share:
11,944
Admin
Author by

Admin

Updated on June 17, 2022

Comments

  • Admin
    Admin about 2 years

    After upgrading Xcode a critical part of my application has stopped working.

    When my app launches I run a function to check boolean flags and set the correct rootViewController.

    But the code I have been using to set this has now stopped working

    class func setLoginAsInitialViewContoller(window:UIWindow) {
        print("SET LOGIN") 
        let storyboard = UIStoryboard(name: "Login", bundle: nil)
        let controller = storyboard.instantiateViewController(withIdentifier: "LoginViewController")
        controller.modalPresentationStyle = .overFullScreen
        window.rootViewController = controller
        window.makeKeyAndVisible()
    }
    

    Specifically when the app gets the the second last line window.rootViewController = controller it crashes with a libc++abi.dylib: terminating with uncaught exception of type NSException error.

    The above function is in a class called Utilities.swift and I am calling the function from within my AppDelegate.swift as shown below:

    class AppDelegate: UIResponder, UIApplicationDelegate {
    
        var window: UIWindow?
        var storyboard: UIStoryboard? = nil
    
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    
            UIApplication.shared.isIdleTimerDisabled = true
            Utilities.decideInitialViewController(window: self.window!)
    
            return true
        }
    

    Any solutions or fixes on how I can set the root controller is much appreciated.

    Thank!

  • Amit Verma
    Amit Verma over 4 years
    where to set rootViewController for notification Clicked. Earlier i was doing this in app_delegate func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { . But on setting rootViewController it is found nil.
  • Rolf Locher
    Rolf Locher about 4 years
    This solved an unrelated problem for me. I used to be able to grab the rootVC in AppDelegate by accessing keyWindow which is deprecated now. Sure enough when opening the app from a url, keywindow is none and the rootVC is some on the windowScene object. Thanks
  • Bhanuteja
    Bhanuteja almost 3 years
    Also, Can you share the code how to use these extensions? Let's say I have to set "LoginVC" as my rootViewController. FYI: My deployment target is iOS 13.0
  • Larry Mickie
    Larry Mickie almost 3 years
    @Bhanuteja sure with these extensions you can do something like : self.window?.rootViewController = LoginVC for example.