场景:用户点击视图控制器上的按钮。视图控制器是导航堆栈中最顶层的(很明显)。tap调用在另一个类上调用的实用程序类方法。这里发生了不好的事情我想在控件返回到视图控制器之前在那里显示一个警告。
+ (void)myUtilityMethod {
// do stuff
// something bad happened, display an alert.
}
这是可能的UIAlertView(但可能不太合适)。
在这种情况下,你如何在myUtilityMethod中呈现UIAlertController ?
几个月前我发过一个类似的问题,我想我终于解决了这个问题。如果你只是想看代码,请点击我文章底部的链接。
解决方案是使用一个额外的UIWindow。
当你想要显示你的UIAlertController:
使你的窗口成为键和可见窗口(window. makekeyandvisible ())
只需使用一个普通的UIViewController实例作为新窗口的rootViewController。(窗口。rootViewController = UIViewController())
在你窗口的rootViewController上显示你的UIAlertController
有几点需要注意:
你的UIWindow必须是强引用的。如果它没有被强引用,它将永远不会出现(因为它已经被释放了)。我建议使用属性,但我也成功地使用了关联对象。
为了确保窗口显示在其他所有内容之上(包括系统UIAlertControllers),我设置了windowLevel。(窗口。windowLevel = UIWindowLevelAlert + 1)
最后,我有一个完整的实现,如果你只是想看看。
https://github.com/dbettermann/DBAlertController
你可以用Swift 2.2做以下事情:
let alertController: UIAlertController = ...
UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(alertController, animated: true, completion: nil)
Swift 3.0:
let alertController: UIAlertController = ...
UIApplication.shared.keyWindow?.rootViewController?.present(alertController, animated: true, completion: nil)
补充Zev的回答(并切换回Objective-C),你可能会遇到这样的情况,你的根视图控制器通过segue或其他东西呈现其他VC。在根VC上调用presenttedviewcontroller会处理这个:
[[UIApplication sharedApplication].keyWindow.rootViewController.presentedViewController presentViewController:alertController animated:YES completion:^{}];
这解决了一个问题,我有根VC已经segue到另一个VC,而不是显示警报控制器,像上面报告的警告发出:
Warning: Attempt to present <UIAlertController: 0x145bfa30> on <UINavigationController: 0x1458e450> whose view is not in the window hierarchy!
我还没有测试它,但如果你的根VC恰好是一个导航控制器,这可能也是必要的。