【问题标题】:NavigationController not displaying after calling rootViewController调用 rootViewController 后 NavigationController 不显示
【发布时间】:2018-05-09 10:44:23
【问题描述】:

我对 Swift 比较陌生 尝试使用 peek and pop previewActionItems "edit" 在编辑模式下打开 SpeciesDetailViewController。尝试让 segue 呈现 SpeciesDetailViewController 时遇到问题,并收到错误消息 "Warning: Attempt to present SpeciesDetailViewController whose view is not in the window hierarchy"。我在found here 上实施了 Jacob Davis 的解决方案。

这修复了窗口层次结构错误,但是当调用 SpeciesDetailViewController 控制器时,导航控制器和 tabBarController 都不会显示。

虽然我认为这是由 SpeciesDetailViewController 被称为顶级 viewController 引起的,但我不知道如何解决这个问题。

你能帮我同时显示导航控制器和tabBarController吗?

以下是我当前的代码:

主视图控制器

func showDetailsViewController() {

    let topVC = topMostController()
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let vc = storyboard.instantiateViewController(withIdentifier: "SpeciesDetailViewController") as! SpeciesDetailViewController
    topVC.present(vc, animated: true, completion: nil)

}

func topMostController() -> UIViewController {
    var topController: UIViewController = UIApplication.shared.keyWindow!.rootViewController!
    while (topController.presentedViewController != nil) {
        topController = topController.presentedViewController!
    }

    return topController
}

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    对于UITabBarControllerUINavigationController,您需要不同的实现。

    这是我用来获取 topMostViewController 的代码:

    protocol TopUIViewController {
        func topUIViewController() -> UIViewController?
    }
    
    extension UIWindow : TopUIViewController {
        func topUIViewController() -> UIViewController? {
            if let rootViewController = self.rootViewController {
                return self.recursiveTopUIViewController(from: rootViewController)
            }
    
            return nil
        }
    
        private func recursiveTopUIViewController(from: UIViewController?) -> UIViewController? {
            if let topVC = from?.topUIViewController() { return recursiveTopUIViewController(from: topVC) ?? from }
            return from
        }
    }
    
    extension UIViewController : TopUIViewController {
        @objc open func topUIViewController() -> UIViewController? {
            return self.presentedViewController
        }
    }
    
    extension UINavigationController {
        override open func topUIViewController() -> UIViewController? {
            return self.visibleViewController
        }
    }
    
    extension UITabBarController {
        override open func topUIViewController() -> UIViewController? {
            return self.selectedViewController ?? presentedViewController
        }
    }
    

    现在您可以使用它从您的应用程序中获取 topUIViewController,而不管您拥有何种 UIViewController 堆栈,包括 UINavigationController、UITabBarViewController。

    let topVC = UIApplication.shared.keyWindow!.rootViewController!.topUIViewController()
    

    【讨论】:

    • 谢谢,Grzegorz。但是,我必须承认我对如何实现这一点有点迷茫。你能举个关于显示 NavigationBar 的例子吗?
    • 我不完全确定,也许我误解了您的问题 - 您可以使用您拥有的 UIViewController 层次结构以及您希望在哪里显示新的 UIViewController 来编辑您的问题吗?
    • Grzegorz,我对其进行了一些更改,但由于我在 Class 中有大约 3000 行,我不确定您需要查看什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多