iOS 13:Swift-'以编程方式设置应用程序根视图控制器'不起作用

Kru*_*nal 6 ios appdelegate swift rootviewcontroller ios13

我在AppDelegate.swift中有以下代码来为iOS应用程序设置根视图控制器。但这行不通。它遵循目标结构(在“常规”选项卡下定义),并忽略此代码。

(Xcode 11,Swift 5.1,iOS 13)

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        window = UIWindow(frame: UIScreen.main.bounds)
        guard let rootVC = UIViewController() else {
            print("Root VC not found")
            return true
        }
        let rootNC = UINavigationController(rootViewController: rootVC)
        window?.rootViewController = rootNC
        window?.makeKeyAndVisible()

        return true
    }
}
Run Code Online (Sandbox Code Playgroud)

无法了解问题出在哪里。

我也尝试了以下参考,但没有运气:

小智 101

要从 Xcode 11 中创建的项目中选择 SwiftUI 支持的先前方法,您可以按照以下步骤操作。

变老的步骤

  • 如果您不打算使用 SwiftUI,或者 SceneDelegate.swift 文件只会占用不必要的空间,那么这是一个很好的解决方案。 (4认同)
  • 这确实是最好的解决办法了! (2认同)

Gur*_*ngh 11

第一种情况

如果您的项目的主要部分是在故事板中构建的,并且在使用 Xcode 11 进行开发之前,并且您没有使用 SwiftUI,则您希望使用与 AppDelegate 关联的旧类。

  • 然后尝试删除 info.pllist 中的“Application Scene Manifest”。
  • 从项目中完全删除ScenceDelegate。

    然后你就可以使用你的旧代码了。

第二种情况

如果您想同时使用 Appdelegte 和 ScenceDelegate,那么下面是工作代码。

应用委托代码:

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
}
Run Code Online (Sandbox Code Playgroud)

场景委托代码:

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
}
Run Code Online (Sandbox Code Playgroud)


Hem*_*vle 10

以下是适用于 iOS 13.x 和 iOS 12.x 及更低版本的内容

对于 iOS 13,在场景委托中

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()
        }
Run Code Online (Sandbox Code Playgroud)

在实用程序类中,我编写了下面的函数来获取window对象并将其分配给appdelegate.window. 根据我的需要,我需要在需要窗口对象的不同场景中的多个位置设置根视图控制器。

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()
    }
}
Run Code Online (Sandbox Code Playgroud)

这对我来说效果很好。希望它也适用于其他人。


Kru*_*nal 7

我尝试了以下两种选择,而这两种选择都对我有用。在iOS-13(Xcode 11)中,默认情况下会启用带有UIWindowScene概念的新文件SceneDelegate.swift。

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()
    }
}
Run Code Online (Sandbox Code Playgroud)

备用:

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()

    }
}
Run Code Online (Sandbox Code Playgroud)

我不知道它为什么以及如何工作,但是它解决了我的问题。

对我有帮助的参考文档:


Uts*_*ave 6

对于SceneDelegate.swift内的 Xcode 11+ 和 Swift 5+


var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let windowScene = scene as? UIWindowScene else { return }
        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()
    }
Run Code Online (Sandbox Code Playgroud)


Vik*_*ary 5

我尝试了以下方法,该方法对我有效,iOS 13iOS 12.4.2从开始进行了测试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()
     }
Run Code Online (Sandbox Code Playgroud)


Ami*_*kur 5

如果您不想使用主故事板,如果您想以编程方式创建自己的视图。

对于 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())
}
Run Code Online (Sandbox Code Playgroud)

这肯定会起作用。谢谢

  • 与现有答案完全相同/sf/answers/4065922871/ (3认同)

Pav*_*art 5

如果您遵循此答案/sf/answers/4065922871/

如果您以编程方式初始化 rootController,您还必须从以下位置删除对主故事板的引用:

  1. 信息.plist。

在此输入图像描述

  1. 部署信息

在此输入图像描述