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

Posted

技术标签:

【中文标题】更改 rootviewcontroller 后,快速导航控制器返回 nil【英文标题】:swift navigation controller return nil after changing rootviewcontroller 【发布时间】:2017-05-29 14:38:17 【问题描述】:

我正在尝试更改我的应用程序的 rootViewController,它运行良好。但是,在更改 rootViewController 后,我的 navigationController 返回 nil。因此,即使是我推送任何新控制器 self.navigationController.pushViewController 的简单代码也不起作用。

在此之前,我想解释一下为什么要更改我的 rootViewController。我已经登录页面(这是初始视图控制器),成功登录后用户将被重定向到 UITabBarController(3 个选项卡)。现在我想将 rootViewController 更改为这个 UITabBarController,我用下面的代码成功地做到了。

    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let destVC = self.storyboard?.instantiateViewController(withIdentifier: "home_view")
    let rootViewController = appDelegate.window?.rootViewController as! UINavigationController
    appDelegate.window?.rootViewController = destVC

现在更改 rootViewController 后,我的所有 3 个选项卡和它们各自的视图控制器都可以正常工作。但是在我的一个视图控制器中,我有一个按钮,单击该按钮时,我想将新控制器推送给用户。现在在这里我面临 nil 返回导航视图控制器的问题。

    let destVC = self.storyboard?.instantiateViewController(withIdentifier: "menu_items_view") as! MenuItems
    self.navigationController?.pushViewController(destVC, animated: true)

当我使用上面的简单代码时,什么也没有发生。我能调试的只是我的 self.navigationController 返回 nil。谁能解释我在流程中的错误是什么?

【问题讨论】:

你确定你的视图层次结构中有一个导航控制器吗?在我看来,您已经删除并删除了它。 @DanielT。是的,我的视图层次结构中有导航控制器。我添加了截图给你看。我正在尝试将根视图控制器更改为 UITabBarController,效果很好。正如您在带有蓝色按钮的 2 个选项卡图像中看到的那样,当我尝试通过单击该按钮来推动另一个控制器时,没有任何反应。 【参考方案1】:

答案很简单,只需将您的“destVC”放入 UINavigationController 中,如下所示:

ios 13 keyWindow 已被弃用,我们需要编写一些代码来获取它,我在 UIApplication 上做了一个扩展来获取 keyWindow

    extension UIApplication 
       static var key: UIWindow? 
         if #available(iOS 13, *) 
            return UIApplication.shared.windows.first  $0.isKeyWindow 
          else 
            return UIApplication.shared.keyWindow
         
      
    

用法:

let rootViewController = UINavigationController(rootViewController: destVC)
UIApplication.key?.rootViewController = rootViewController

上一个答案

let rootViewController = UINavigationController(rootViewController: destVC)
    UIApplication.shared.keyWindow?.rootViewController = rootViewController 

【讨论】:

【参考方案2】:

您已从视图层次结构中删除了导航控制器。让我们看看您发布的代码:

let appDelegate = UIApplication.shared.delegate as! AppDelegate
let destVC = self.storyboard?.instantiateViewController(withIdentifier: "home_view")
let rootViewController = appDelegate.window?.rootViewController as! UINavigationController
// at this point your window's root view controller is a navigation controller.
appDelegate.window?.rootViewController = destVC
// In the above, you replaced the navigation controller with your destVC.

这就像你脱下运动鞋穿上正装鞋,然后你在问为什么你的运动鞋不再穿在你的脚上。


解决方案是在标签栏控制器和需要导航控制器的视图控制器之间放置一个导航控制器

【讨论】:

以上是关于更改 rootviewcontroller 后,快速导航控制器返回 nil的主要内容,如果未能解决你的问题,请参考以下文章

iOS在Objective-C中登录/注销过程后更改rootViewController

iOS如何在dismissController时更改rootViewController

在 applicaitonWillEnterForeground 中更改 rootViewController

如何更改 rootViewController 的视图?

更改 rootViewController 时 UIWindow 导致黑屏

在 RootViewController 中单击按钮更改 DetailViewController