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

后端 未结 14 954
北恋
北恋 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:20

    First Case

    If major of your project is build in storyboard and before Xcode 11 is used for development and you are not using SwiftUI you want to use your old classes associated with AppDelegate.

    • Then try to remove "Application Scene Manifest" in info.pllist.
    • Remove ScenceDelegate from project completely.

      Then you will able to use your old code.

    Second Case

    If you want to use both Appdelegte and ScenceDelegate then below is working code.

    App Delegate Code:

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {   
     if #available(iOS 13.0, *){
        //do nothing we will have a code in SceneceDelegate for this 
    } else {
        let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let VC = mainStoryboard.instantiateViewController(withIdentifier: "LoginVC") as! LoginVC
        navigationController?.isNavigationBarHidden = true
        navigationController = UINavigationController(rootViewController: VC)
        navigationController?.isNavigationBarHidden = true // or not, your choice.
        self.window = UIWindow(frame: UIScreen.main.bounds)
        self.window!.rootViewController = navigationController
    }
    return true
    }
    

    ScenceDelegate Code:

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    
        let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let VC = mainStoryboard.instantiateViewController(withIdentifier: "LoginVC") as! LoginVC
        navigationController?.isNavigationBarHidden = true
        guard let windowScene = (scene as? UIWindowScene) else { return }
        self.window = UIWindow(frame: windowScene.coordinateSpace.bounds)
        window.windowScene = windowScene
        window.rootViewController = VC
        window.makeKeyAndVisible()
        let appDelegate = UIapplication.shared.delegate as! AppDelegate
        appDelegate.window = window
    }
    
    0 讨论(0)
  • 2020-12-01 02:21
    let controller = ....
    let keyWindow = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
    keyWindow?.rootViewController = controller
    keyWindow?.makeKeyAndVisible()
    

    These are the basic code required to set root view controller.

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

    To choose a previous approach to the one supported by SwiftUI, from a project created in Xcode 11, you can follow these steps.

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

    I just deleted a row on the info.plist that says something about Application scene. Works for me.

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

    If you follow this answer https://stackoverflow.com/a/58084612/6667477

    and if you initialise a rootController programmatically you also have to remove reference to main storyboard from:

    1. Info.plist.

    1. Deployment info

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

    I tried following two options and both of these working for me. With iOS-13 (Xcode 11) a new file SceneDelegate.swift with the concept of UIWindowScene is enabled by default.

    class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    
        var window: UIWindow?
    
    
        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 =  UIWindow(frame: UIScreen.main.bounds)
    
            let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil)
            guard let rootVC = storyboard?.instantiateViewController(identifier: "ViewControllerIdentifierName") as? ViewController else {
                print("ViewController not found")
                return
            }
            let rootNC = UINavigationController(rootViewController: rootVC)
            self.window?.rootViewController = rootNC
            self.window?.makeKeyAndVisible()
        }
    }
    

    Alternate:

    class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    
        var window: UIWindow?
    
    
        func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
            let windowScene = UIWindowScene(session: session, connectionOptions: connectionOptions)
            self.window = UIWindow(windowScene: windowScene)
            //self.window =  UIWindow(frame: UIScreen.main.bounds)
            let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil)
            guard let rootVC = storyboard?.instantiateViewController(identifier: "ViewControllerIdentifierName") as? ViewController else {
                print("ViewController not found")
                return
            }
            let rootNC = UINavigationController(rootViewController: rootVC)
            self.window?.rootViewController = rootNC
            self.window?.makeKeyAndVisible()
    
        }
    }
    

    I don't know, why and how it works but it resolved my problem.

    Reference docs that helped me:

    • init(windowScene:)
    • UIWindow
    • rootViewController
    0 讨论(0)
提交回复
热议问题