遗留UIAlertView
和新UIAlertController
之间的区别在于后者需要使用presentViewController:animated:completion:
呈现到特定的视图控制器上。这给我的用例带来了一个尴尬的问题:当第二个视图控制器出现时(例如,由于网络连接失败而导致的错误对话),如果已经有UIAlertController
显示(例如评级对话框),该怎么办?我经历过,在这种情况下,第二个UIAlertController
只是没有显示。
编辑:在我尝试显示警报的那一刻,我不知道当前是否有任何呈现。
你如何应对这种情况?
答案 0 :(得分:5)
我找到了一个解决方法,找出我可以提供警报的视图控制器。我还发布了答案here:
@implementation UIViewController (visibleViewController)
- (UIViewController *)my_visibleViewController {
if ([self isKindOfClass:[UINavigationController class]]) {
// do not use method visibleViewController as the presentedViewController could beingDismissed
return [[(UINavigationController *)self topViewController] my_visibleViewController];
}
if ([self isKindOfClass:[UITabBarController class]]) {
return [[(UITabBarController *)self selectedViewController] my_visibleViewController];
}
if (self.presentedViewController == nil || self.presentedViewController.isBeingDismissed) {
return self;
}
return [self.presentedViewController my_visibleViewController];
}
@end
// To show a UIAlertController, present on the following viewcontroller:
UIViewController *visibleViewController = [[UIApplication sharedApplication].delegate.window.rootViewController my_visibleViewController];
答案 1 :(得分:4)
由于UIAlertController
本身就是UIViewController
,因此您可以通过现有的UIAlertController
呈现第二个alertController.PresentViewController(alertController2, animated: true, completionHandler: null)
:
{{1}}
答案 2 :(得分:0)
当app必须在窗口上呈现一些警告并且在呈现之前检查是否已经存在任何其他AlertController,如果呈现然后出现警报出现在AlertController上,否则在窗口上显示警告时,此代码满足要求。
这是另一种选择,您可以根据您的要求进行优化。
func showAlert(message:String) {
if let alert = self.checkIfAlertViewHasPresented() {
alert.presentViewController(alertController, animated: true, completion: nil)
} else {
self.window?.rootViewController!.presentViewController(alertController, animated: true, completion: nil)
}
}
func checkIfAlertViewHasPresented() -> UIAlertController? {
if var topController = UIApplication.sharedApplication().keyWindow?.rootViewController {
while let presentedViewController = topController.presentedViewController {
topController = presentedViewController
}
if topController is UIAlertController {
return (topController as! UIAlertController)
} else {
return nil
}
}
return nil
}
答案 3 :(得分:0)
这就是我正在使用的。这样,如果已经显示警报, 我更喜欢用户解雇它而不是应用程序。 因此,如果视图已经显示警报,我只需等待5秒钟再试一次。
我只是想补充一下,我没有太多测试,但它确实有效。(从我做过的一次测试中),所以我希望我不会错过任何东西,因为我长时间想到这个问题,这个解决方案听起来太容易了:)
-(void) alertUserWithTitle:(NSString*) title Message:(NSString*) message
{
UIAlertController* alert = [UIAlertController alertControllerWithTitle:title message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[alert addAction:defaultAction];
if(self.presentedViewController == nil)
{
[self presentViewController:alert animated:YES completion:nil];
}else
{
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self alertUserWithTitle:title Message:message];
});
}
}
答案 4 :(得分:0)
这是我在Swift 3中使用的解决方案。它是一个向用户显示警报的功能,如果在用户解除警报之前多次调用它,它会将新警报文本添加到警报中已经出现了。如果正在显示其他视图,则不会显示警报。并非所有人都同意这种行为,但它适用于简单的情况。
extension UIViewController {
func showAlert(_ msg: String, title: String = "") {
if let currentAlert = self.presentedViewController as? UIAlertController {
currentAlert.message = (currentAlert.message ?? "") + "\n\nUpdate:\(title): \(msg)"
return
}
// create the alert
let alert = UIAlertController(title: title, message: msg, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
// show the alert
self.present(alert, animated: true, completion: nil)
}
}