在iOS Swift中获取顶级ViewController

gut*_*uhu 6 uiwindow uialertview viewcontroller swift

我想实现一个单独的ErrorHandler类,它显示某些事件的错误消息.应该从不同的其他类调用此类的行为.发生错误时,它将具有UIAlertView输出.此AlertView的显示应始终位于顶部.因此无论从何处抛出Error,最顶层的viewController都应该显示AlertMessage(例如,当异步后台进程失败时,我想要一条错误消息,无论前景中显示什么View).

我找到了几个似乎可以解决我的问题的要点(见下面的代码).但是调用UIApplication.sharedApplication().keyWindow?.visibleViewController()确实会返回一个零值.

从要点扩展

extension UIWindow {
func visibleViewController() -> UIViewController? {
if let rootViewController: UIViewController  = self.rootViewController {
  return UIWindow.getVisibleViewControllerFrom(rootViewController)
}
return nil
}

class func getVisibleViewControllerFrom(vc:UIViewController) -> UIViewController {

if vc.isKindOfClass(UINavigationController.self) {

  let navigationController = vc as! UINavigationController
  return UIWindow.getVisibleViewControllerFrom( navigationController.visibleViewController)

} else if vc.isKindOfClass(UITabBarController.self) {

  let tabBarController = vc as! UITabBarController
  return UIWindow.getVisibleViewControllerFrom(tabBarController.selectedViewController!)

} else {

  if let presentedViewController = vc.presentedViewController {

    return UIWindow.getVisibleViewControllerFrom(presentedViewController.presentedViewController!)

  } else {

    return vc;
  }
}
}
}
Run Code Online (Sandbox Code Playgroud)

gut*_*uhu 23

Amit89为解决方案带来了一条道路.你必须调用.windowAppDelegate 的属性.所以我从下面的链接更改了Swift代码,以便找到最顶层的ViewController.确保视图已在视图层次结构中.所以这个方法不能从a调用.viewDidLoad

扩展以找到最顶层的ViewController*

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)
    }
    return base
  }
}
Run Code Online (Sandbox Code Playgroud)

此代码源自GitHub用户Yonat对objectiveC等效的注释.我只更改了代码位以使其在没有.keyWindow属性的情况下工作

  • 我使用你的扩展来找到最顶层的ViewController,但是如果出现alert,上面的代码给出了UIAlertController.如何在UIAlertController下获得顶视图控制器? (10认同)