在当前活动的UIViewController

时间:2016-04-06 20:17:32

标签: ios swift uiviewcontroller alert

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

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

我现在这样做的方法是给观察者一个通知我的每个视图控制器的方法,以及创建和显示该警报的方法。

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

这是我的代码:

// 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)
}

非常感谢任何想法!

3 个答案:

答案 0 :(得分:1)

您可以在导航堆栈中找到热门ViewController,然后直接在此处显示AlertController。您可以使用此处发布的扩展方法从应用程序的任何位置查找热门ViewController

https://stackoverflow.com/a/30858591/2754727

答案 1 :(得分:1)

这实际上取决于您的导航架构。 首先,您需要当前的VC。如果您已将根视图控制器作为导航控制器并且未显示任何模态,则可以从rootVC获取当前VC。如果你有混合导航。即tabbar和内部的导航控制器,可能有一些模态形成它们,你可以在AppDelegate上编写一个扩展,它将搜索并返回当前的VC。

现在你应该把这个计时器类固定在某个地方 - 它可能是一个单身人士,或者只是固定在某个地方。在此计时器类中,当计时器结束时,您可以查找当前VC(使用AppDelegate的扩展方法或引用根导航控制器),并在其上显示警报。

答案 2 :(得分:1)

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

有了这个,您可以轻松地显示您的提醒

UIApplication.topMostViewController?.present(alert, animated: true, completion: nil)

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

,则返回nil
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
        }
    }
}