一尘不染

在iOS Swift中获得顶级ViewController

swift

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

我发现一些要点似乎可以解决我的问题(请参见下面的代码)。但是调用UIApplication.sharedApplication().keyWindow?.visibleViewController()确实会返回nil值。

从主旨延伸

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;
  }
}
}
}

阅读 435

收藏
2020-07-07

共1个答案

一尘不染

Amit89提供了一种解决方案。您必须调用.windowAppDelegate
的属性。因此,我从下面的链接中更改了Swift代码,使其可以正常工作以找到最顶层的ViewController。确保该视图已经在视图层次结构中。因此,无法从.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
  }
}

该代码源自GitHub用户Yonat,它是对ObjectiveC等效项的注释。我只更改了一些代码,以使其在没有该.keyWindow属性的情况下也能正常工作

2020-07-07