在当前活动的 UIViewController 中呈现 UIAlertController

non*_*tic 4 alert uiviewcontroller ios swift

我有一个计时器,在完成时显示警报。此警报视图应显示在用户当前所在的视图控制器中。

我的感觉是这可以比以下更有效:

我现在这样做的方法是向我的 5 个视图控制器中的每一个提供通知的观察者,以及创建和呈现该警报的方法。

有没有办法只设置一次警报,然后将其显示在当前处于活动状态的视图控制器中?

这是我的代码:

// I've got the following in each of my view controllers.

// In viewDidLoad()
override func viewDidLoad() {
  super.viewDidLoad()
  NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(SonglistViewController.presentSleepTimerFinishedAlert(_:)), name: "presentSleepTimerFinishedAlert", object: nil)
}


func presentTimerFinishedAlert(notification: NSNotification) {
  let alertController = UIAlertController(title: "Timer finished", message: nil, preferredStyle: UIAlertControllerStyle.Alert)
  alertController.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
  presentViewController(alertController, animated: true, completion: nil)
}
Run Code Online (Sandbox Code Playgroud)

非常感谢您的任何想法!

NSE*_*nal 6

extension UIApplication {
    /// The top most view controller
    static var topMostViewController: UIViewController? {
        return UIApplication.shared.keyWindow?.rootViewController?.visibleViewController
    }
}

extension UIViewController {
    /// The visible view controller from a given view controller
    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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

有了这个,您可以轻松地像这样显示您的警报

UIApplication.topMostViewController?.present(alert, animated: true, completion: nil)
Run Code Online (Sandbox Code Playgroud)

需要注意的一件事是,如果当前正在显示 UIAlertController,UIApplication.topMostViewController将返回一个UIAlertController. 呈现在 a 之上UIAlertController有奇怪的行为,应该避免。因此,您应该!(UIApplication.topMostViewController is UIAlertController)在呈现之前手动检查,或者添加一个else if案例以返回 nil 如果self is UIAlertController

extension UIViewController {
    /// The visible view controller from a given view controller
    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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)