我使用以下扩展名来查找top most ViewController。
如果出现提醒,则上面的代码会显示UIAlertController
。
如何在 UIAlertController
下获得顶视图控制器?
答案 0 :(得分:2)
创建如下所示的UIApplication扩展,UIApplication.topViewController()
将返回UIViewController
下最上面的UIAlertController
extension UIApplication {
class func topViewController(controller: UIViewController? = UIApplication.shared.windows.first?.rootViewController) -> UIViewController? {
if let navigationController = controller as? UINavigationController {
return topViewController(controller: navigationController.visibleViewController)
}
if let tabController = controller as? UITabBarController {
if let selected = tabController.selectedViewController {
return topViewController(controller: selected)
}
}
if let presented = controller?.presentedViewController {
return topViewController(controller: presented)
}
if let alert = controller as? UIAlertController {
if let navigationController = alert.presentingViewController as? UINavigationController {
return navigationController.viewControllers.last
}
return alert.presentingViewController
}
return controller
}
}
extension UIApplication {
class func topViewController(controller: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
if let navigationController = controller as? UINavigationController {
return topViewController(controller: navigationController.visibleViewController)
}
if let tabController = controller as? UITabBarController {
if let selected = tabController.selectedViewController {
return topViewController(controller: selected)
}
}
if let presented = controller?.presentedViewController {
return topViewController(controller: presented)
}
if let alert = controller as? UIAlertController {
if let navigationController = alert.presentingViewController as? UINavigationController {
return navigationController.viewControllers.last
}
return alert.presentingViewController
}
return controller
}
}
答案 1 :(得分:1)
您可以使用UIAlertController
属性
presentingViewController
的父控制器
extension UIApplication {
class func topViewController(base: UIViewController? = (UIApplication.sharedApplication().delegate as! AppDelegate).window?.rootViewController) -> UIViewController? {
if let nav = base as? UINavigationController {
return topViewController(base: nav.visibleViewController)
}
if let tab = base as? UITabBarController {
if let selected = tab.selectedViewController {
return topViewController(base: selected)
}
}
if let alert = base as? UIAlertController {
if let presenting = alert.presentingViewController {
return topViewController(base: presenting)
}
}
if let presented = base?.presentedViewController {
return topViewController(base: presented)
}
return base
}
}
在代码中使用这些更改,未在XCode上进行测试。
答案 2 :(得分:0)
您可以检查下一个viewController是否为UIAlertController
,如果是,则返回其父级。像这样:
if let presented = base as? UIAlertController {
return base.presentingViewController
}
在返回之前使用的扩展名中添加此内容。
<强>更新强>
extension UIApplication {
class func topViewController(base: UIViewController? = (UIApplication.sharedApplication().delegate as! AppDelegate).window?.rootViewController) -> UIViewController? {
if let nav = base as? UINavigationController {
return topViewController(base: nav.visibleViewController)
}
if let tab = base as? UITabBarController {
if let selected = tab.selectedViewController {
return topViewController(base: selected)
}
}
if let presented = base?.presentedViewController {
return topViewController(base: presented)
}
if let alert = base as? UIAlertController {
return alert.presentingViewController
}
return base
}
}
答案 3 :(得分:0)
我使用此扩展来获取UIAlertController下的最顶层视图控制器,基本上我做的是当我找到一个UIAlertController时停止寻找顶视图控制器。
extension UIApplication {
var topViewController: UIViewController? {
var viewController = keyWindow?.rootViewController
guard viewController != nil else { return nil }
var presentedViewController = viewController?.presentedViewController
while presentedViewController != nil, !(presentedViewController is UIAlertController) {
switch presentedViewController {
case let navagationController as UINavigationController:
viewController = navagationController.viewControllers.last
case let tabBarController as UITabBarController:
viewController = tabBarController.selectedViewController
default:
viewController = viewController?.presentedViewController
}
presentedViewController = viewController?.presentedViewController
}
return viewController
}
}
答案 4 :(得分:0)
我认为你想在当前顶级可见VC上推出一个新的VC,这是一个UIAlertController,然后这个UIAlertController会立即消失,导致新的VC被解雇。最后,你无法推动新的VC。
问题是,如果您新建一个UIAlertView,然后调用show
,Cocoa Touch将初始化一个新窗口,其中rootViewController是UIApplicationRotationFollowingController,其presentationViewController是UIAlertController。所以你不能遍历UIAlertController下最顶层的VC,因为它存在于另一个窗口中!
因此,如果topViewController
遍历keyWindow?.rootViewController
,请找到UIAlertController
,再次致电topViewController
,但要从window
遍历您想要的内容,例如{{1} }}
答案 5 :(得分:0)
这是正确的:
func firstApplicableViewController() -> UIViewController? {
if (self is UITabBarController) {
let tabBarController = self as? UITabBarController
return tabBarController?.selectedViewController?.firstApplicableViewController()
} else if (self is UINavigationController) {
let navigationController = self as? UINavigationController
return navigationController?.visibleViewController?.firstApplicableViewController()
} else if (self is UIAlertController) {
let presentingViewController: UIViewController = self.presentingViewController!
return presentingViewController.firstApplicableViewController()
} else if self.presentedViewController != nil {
let presentedViewController: UIViewController = self.presentedViewController!
if (presentedViewController is UIAlertController) {
return self
} else {
return presentedViewController.firstApplicableViewController()
}
} else {
return self
}
}