iOS 13: Swift - 'Set application root view controller programmatically' does not work

后端 未结 14 956
北恋
北恋 2020-12-01 01:43

I have following code in my AppDelegate.swift to setup root view controller for an iOS application. But it does not work. It follows Target structure (defined under General

相关标签:
14条回答
  • 2020-12-01 02:29

    For Xcode 11+ and Swift 5+ inside SceneDelegate.swift

    
    var window: UIWindow?
    
        func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
            if let windowScene = scene as? UIWindowScene {
                let window = UIWindow(windowScene: windowScene)
                let submodules = (
                    home: HomeRouter.createModule(),
                    search: SearchRouter.createModule(),
                    exoplanets: ExoplanetsRouter.createModule()
                )
                
                let tabBarController = TabBarModuleBuilder.build(usingSubmodules: submodules)
                
                window.rootViewController = tabBarController
                self.window = window
                window.makeKeyAndVisible()
            }
        }
    
    0 讨论(0)
  • 2020-12-01 02:33
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    
        guard let windowScene = (scene as? UIWindowScene) else { return }
        self.window = UIWindow(windowScene: windowScene)               
          self.window?.makeKeyAndVisible()
    
        let layout = UICollectionViewFlowLayout()
        let swipingController = SwipingController(collectionViewLayout: layout)
              self.window?.rootViewController = swipingController       
    
    }
    
    0 讨论(0)
  • 2020-12-01 02:35

    I tried the following approach and it's working for me in iOS 13 and also tested on iOS 12.4.2 from Xcode 11.

    func resetRoot() {
                guard let rootVC = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewController") as? ViewController else {
                    return
                }
                let navigationController = UINavigationController(rootViewController: rootVC)
    
                UIApplication.shared.windows.first?.rootViewController = navigationController
                UIApplication.shared.windows.first?.makeKeyAndVisible()
         }
    
    0 讨论(0)
  • 2020-12-01 02:35

    If you don't want to use main storyboard, if you want to create you own views programmatically.

    For xcode 11.

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

        guard let windowScene = (scene as? UIWindowScene) else { return }
        window = UIWindow(windowScene: windowScene)
        window?.makeKeyAndVisible()
        window?.rootViewController = UINavigationController(rootViewController:      ViewController())
    }
    

    This will defenetily work. Thanks

    0 讨论(0)
  • 2020-12-01 02:38

    I did two things. Firstly I set a Notification into SceneDelegate, then when I needed to change the RootViewController I did a Notification Post and it worked. But it's an anwful solution.

    After that

    My boss recommended me to change the Controllers of the NavigationController, something like this:

    func logged() {
        let mainStoryboard: UIStoryboard = UIStoryboard(name: "MainTabViewController", bundle: nil)
        let mainVC = mainStoryboard.instantiateInitialViewController()
    
        self.navigationController?.setViewControllers([mainVC!], animated: false)
    }
    

    I know that perhaps it's not the best solution, but I see it cleaner.
    I'm working now on iOS 13 and I didn't want to use deprecated things.

    0 讨论(0)
  • 2020-12-01 02:41

    Here's what work for both iOS 13.x and iOS 12.x and below

    For iOS 13,In the Scene Delegate

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
                guard let windowScene = (scene as? UIWindowScene) else { return }
                self.window = UIWindow(frame: windowScene.coordinateSpace.bounds)
               //Make sure to do this else you won't get 
               //the windowScene object using UIApplication.shared.connectedScenes
                self.window?.windowScene = windowScene 
                let storyBoard: UIStoryboard = UIStoryboard(name: storyBoardName, bundle: nil)
                window?.rootViewController = storyBoard.instantiateInitialViewController()
                window?.makeKeyAndVisible()
            }
    

    In a utility class, I wrote below function to get the window object and assign it to the appdelegate.window. According to my needs, I needed to set root view controller at multiple places in different scenarios for which I needed the window object.

    static func redirectToMainNavRVC(currentVC: UIViewController){
            let appDelegate = UIApplication.shared.delegate as! AppDelegate
            let vc = UIStoryboard(name: appDelegate.storyBoardName, bundle: nil).instantiateViewController(withIdentifier: "MainNavigationViewController") as! MainNavigationViewController
        if #available(iOS 13.0, *){
            if let scene = UIApplication.shared.connectedScenes.first{
                guard let windowScene = (scene as? UIWindowScene) else { return }
                print(">>> windowScene: \(windowScene)")
                let window: UIWindow = UIWindow(frame: windowScene.coordinateSpace.bounds)
                window.windowScene = windowScene //Make sure to do this
                window.rootViewController = vc
                window.makeKeyAndVisible()
                appDelegate.window = window
            }
        } else {
            appDelegate.window?.rootViewController = vc
            appDelegate.window?.makeKeyAndVisible()
        }
    }
    

    This worked well for me. Hopefully, it works for others too.

    0 讨论(0)
提交回复
热议问题