这个解决方案提供了顶层视图控制器,让您可以在呈现之前处理任何特殊情况。例如,也许您只想在最顶层的视图控制器不是特定的视图控制器时才呈现您的视图控制器。
extension UIApplication {
static var topMostViewController: UIViewController? {
return UIApplication.shared.keyWindow?.rootViewController?.visibleViewController
}
}
extension UIViewController {
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
。在一个 UIAlertController
上面呈现会有奇怪的行为,应该避免这样做。因此,在呈现之前,你应该手动检查 !(UIApplication.topMostViewController is UIAlertController)
或者在 self is UIAlertController
的情况下添加一个 else if
语句来返回 nil。
extension UIViewController {
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
}
}
}