更改 rootViewController 时 UIWindow 导致黑屏

Posted

技术标签:

【中文标题】更改 rootViewController 时 UIWindow 导致黑屏【英文标题】:UIWindow results in a black screen when changing the rootViewController 【发布时间】:2018-06-15 08:36:56 【问题描述】:

我将从主要问题开始:我的问题不容易重现。

所以...在我的应用程序中,根据用户是否是第一次打开它,我正在更改 rootViewController。

我是这样做的:

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate 

    var window: UIWindow?

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

        if /* code to figure out if it's the first launch */ 

            let storyboard = UIStoryboard(name: "Onboarding", bundle: nil)
            let onboardingViewController = storyboard.instantiateInitialViewController()

            window?.rootViewController = onboardingViewController
        

        return true
    

这基本上很好用!由于我目前正在构建 Onboarding ViewController,因此我删除了 if,因此它总是会显示出来。这也很好用,但突然之间,该应用程序将不再启动。屏幕保持黑色。然后我在另一台设备上运行完全相同的代码,它在那里工作。 顺便提一句。上面的代码就是我的 AppDelegate 中的全部内容,如果 OnboardingVC 将所有内容都注释掉,问题仍然存在。

查看我的应用程序的 UI 调试器时,它看起来也很奇怪: 通常,UIWindow 旁边会有一个箭头,表明它的 root 确实是我的 VC,但在我的情况下,情况并非如此。

我不介意,只是从我的设备中删除该应用程序,然后重新安装,但我有一个用户投诉我的另一个应用程序,该应用程序用户的逻辑相同,他告诉我确切的问题。现在我基本上重现了这个问题,但不知道问题应该出在哪里。

顺便说一句,我的应用正在使用情节提要。

也许有人以前遇到过这个问题,并且知道可能是什么问题。

编辑

今天又遇到了这个问题...这里有一些更多的观察: 当我启动我的 ViewController 并输出它的视图时,它是不正确的。这不是故事板中真正设置的视图。这是一个随机的其他视图。 故事板是否可能已损坏?如果是这样……我能做些什么呢? 在我将一个随机子视图添加到我的 Main-View-Controllers 视图并再次运行后,它又可以工作了……所以显然故事板不知何故损坏了?

好吧……在开发的时候……好吧……但是对于一个已经存在的应用程序,故事板突然损坏了……这真的很糟糕!!!!

以前有人遇到过这个问题吗?又该如何解决呢?

【问题讨论】:

能否分享完整的切换代码 你写的是window.makeKeyAndVisible()吗? 您是否检查过要显示的视图控制器在情节提要中是否仍标记为初始视图控制器? 上面的代码就是全部...我试过makeKeyAndVisible...没有区别。是的,VC 是故事板中的第一个。当我重新安装应用程序或在不同的设备上运行时它可以工作......这就是它如此奇怪的原因...... @Georg 在你的情况下任何窗口对象是 nil 所以你可以初始化你的窗口对象错误将解决检查下面的答案 【参考方案1】:

试试这个 在您的情况下,窗口为零,所以

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate 

    var window: UIWindow?

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

        window = UIWindow(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height))
        if /* code to figure out if it's the first launch */ 

            let storyboard = UIStoryboard(name: "Onboarding", bundle: nil)
            let onboardingViewController = storyboard.instantiateInitialViewController()

            window?.rootViewController = onboardingViewController
        
        return true
    

【讨论】:

嘿Sumit,问题是窗口不是零。它就在那里......我真的不明白这个问题...... :(【参考方案2】:

我终于找到了问题所在。无论出于何种原因,我显然将我的 Initial-View-Controller 的视图出口双重链接到子视图。所以它有两个到 view 属性的出口(这怎么可能?) 它在启动时随机选择或其他.... 用一个非常敏锐的眼光看问题:)

【讨论】:

以上是关于更改 rootViewController 时 UIWindow 导致黑屏的主要内容,如果未能解决你的问题,请参考以下文章

当使用 view.window?.rootViewController 根据 if 语句更改视图时,嵌入式控制器不会被激活

更改窗口 rootViewController 后出现 UITabBarController

更改 UISplitView 中的 RootViewController

ios:更改 window.rootViewController 和内存管理

更改 rootviewcontroller 后,快速导航控制器返回 nil

在 applicaitonWillEnterForeground 中更改 rootViewController