该解决方案为您提供了最顶级的视图控制器,以便您可以在呈现之前处理任何特殊情况。例如,也许您只想在最顶层的视图控制器不是特定的视图控制器时才显示您的视图控制器。
extension UIApplication {
/// The top most view controller
static var topMostViewController: UIViewController? {
return UIApplication.shared.keyWindow?.rootViewController?.visibleViewController
}
}
extension UIViewController {
/// The visible view controller from a given view controller
var visibleViewController: UIViewController? {
if let navigationController = self as? UINavigationController {
return navigationController.topViewController?.visibleViewController
} else if let tabBarController = self as? UITabBarController {
return tabBarController.selectedViewController?.visibleViewController
} else if let presentedViewController = presentedViewController {
return presentedViewController.visibleViewController
} else {
return self
}
}
}
有了这个,您可以从任何地方展示您的视图控制器,而无需知道最顶层的视图控制器是什么
UIApplication.topMostViewController?.present(viewController, animated: true, completion: nil)
或者仅当最顶层的视图控制器不是特定的视图控制器时才显示您的视图控制器
if let topVC = UIApplication.topMostViewController, !(topVC is FullScreenAlertVC) {
topVC.present(viewController, animated: true, completion: nil)
}
需要注意的一点是,如果当前正在显示 UIAlertController,UIApplication.topMostViewController
将返回一个UIAlertController
. 在 a 之上呈现UIAlertController
有奇怪的行为,应该避免。因此,您应该!(UIApplication.topMostViewController is UIAlertController)
在呈现之前手动检查,或者添加一个else if
案例以返回 nil ifself is UIAlertController
extension UIViewController {
/// The visible view controller from a given view controller
var visibleViewController: UIViewController? {
if let navigationController = self as? UINavigationController {
return navigationController.topViewController?.visibleViewController
} else if let tabBarController = self as? UITabBarController {
return tabBarController.selectedViewController?.visibleViewController
} else if let presentedViewController = presentedViewController {
return presentedViewController.visibleViewController
} else if self is UIAlertController {
return nil
} else {
return self
}
}
}