抓住当前导航控制器的正确方法

时间:2018-08-01 03:38:19

标签: ios swift

鉴于我有rootViewController,即UIApplication.shared.delegate?.window??.rootViewController,我想获取活动的导航控制器(如果有)。

到目前为止,我想出了什么:

guard var controller = rootViewController?.presentedViewController else { return rootViewController as? UINavigationController }
while let presented = controller.presentedViewController {
    controller = presented
}
controller = controller.navigationController ?? controller
return controller as? UINavigationController

够了吗?一位同事为我提供了此解决方案,但我不了解的部分是rootViewController?.presentedViewController。应该不是rootViewController?.presentingViewController吗?

2 个答案:

答案 0 :(得分:2)

使用以下扩展名可以获取顶部/当前可见视图控制器和顶部导航控制器。

extension UIApplication {

    class func topViewController(_ viewController: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
        if let nav = viewController as? UINavigationController {
            return topViewController(nav.visibleViewController)
        }
        if let tab = viewController as? UITabBarController {
            if let selected = tab.selectedViewController {
                return topViewController(selected)
            }
        }
        if let presented = viewController?.presentedViewController {
            return topViewController(presented)
        }
        return viewController
    }

    class func topNavigation(_ viewController: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UINavigationController? {

        if let nav = viewController as? UINavigationController {
            return nav
        }
        if let tab = viewController as? UITabBarController {
            if let selected = tab.selectedViewController {
                return selected.navigationController
            }
        }
        return viewController?.navigationController
    }
}

如何使用?

let objViewcontroller = UIApplication.topViewController()

OR

let objNavigationController = UIApplication.topNavigation()

答案 1 :(得分:0)

<块引用>

这就够了吗?

只有你知道。它在您的情况下是否可靠地工作?如果是,它可能足以满足您的需求。但这不是普遍正确的答案。

正如@vivekDas 在评论中提到的那样,一种更可靠的方法是使用 navigationController 方法,该方法返回图中最近的视图控制器,即导航控制器。

<块引用>

...我不明白的部分是rootViewController?.presentedViewController。不应该是rootViewController?.presentingViewController吗?

没有。假设您有两个视图控制器,aba 呈现 b。在这种情况下,a.presentedViewControllerb,而 b.presentingViewControllera。所以 rootViewController.presentedViewControllerrootViewController 呈现的视图控制器。 rootViewController.presentingViewController 将是呈现 rootViewController 的控制器。但是 rootViewController 是视图控制器对象图的根;根据定义,它没有被任何其他视图控制器呈现,因此 rootViewController.presentingViewController 将始终为零。