Получите верхний ViewController в iOS Swift

Я хочу реализовать отдельный class ErrorHandler, который отображает сообщения об ошибках для определенных событий. Поведение этого classа должно вызываться из разных других classов. При возникновении ошибки он будет иметь выход UIAlertView . Дисплей этого AlertView должен ВСЕГДА быть на высоте. Поэтому, независимо от того, откуда возникает ошибка, верхний viewController должен отображать AlertMessage (например, при сбое асинхронного фонового процесса я хочу получить сообщение об ошибке, независимо от того, какой вид отображается на переднем плане).

Я нашел несколько gists, которые, кажется, решают мою проблему (см. Код ниже). Но вызов 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; } } } } 

Amit89 поднял путь к решению. Вы должны вызвать свойство .window AppDelegate. Поэтому я изменил код 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

Вы пробовали это по той же ссылке?

 let appDelegate = UIApplication.sharedApplication().delegate as! MYAppDelegate//Your app delegate class name. extension UIApplication { class func topViewController(base: UIViewController? = 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 } } 
  • Оператор равенства Swift для вложенных массивов
  • Аланофир-асинхронное завершениеHandler для запроса JSON
  • Меню боковой панели слайдов IOS 8 Swift
  • Запрос AlamoFire GET api не работает должным образом
  • Обратный диапазон в Swift
  • Как импортировать файл Swift из другого файла Swift?
  • Получить наибольший UIViewController
  • Преобразование типов при использовании протокола в Swift
  • почему я получаю «Должен переводить авторезистирующую маску в ограничения, чтобы иметь _setHostsLayoutEngine: YES» в xcode 6 beta
  • развертывание нескольких опций в выражении if
  • Использование вывода Swift 3 @objc в режиме Swift 4 устарело?
  • Давайте будем гением компьютера.