Ios 只允许从可见视图上的类显示一个UIAlertController视图
每当我收到来自主题的消息时,我需要显示来自AppDelegate的UIAlertController 我找到了关于如何从AppDelegate显示UIAlertController的代码Ios 只允许从可见视图上的类显示一个UIAlertController视图,ios,objective-c,uialertcontroller,Ios,Objective C,Uialertcontroller,每当我收到来自主题的消息时,我需要显示来自AppDelegate的UIAlertController 我找到了关于如何从AppDelegate显示UIAlertController的代码 UIWindow* topWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; topWindow.rootViewController = [UIViewController new]; topWindo
UIWindow* topWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
topWindow.rootViewController = [UIViewController new];
topWindow.windowLevel = UIWindowLevelAlert + 1;
UIAlertController *uiAlert= ...
topWindow.hidden = YES;
在我的故事板的任何视图上显示警报都没有问题。问题是,每当我收到来自主题的多条消息时,它也会多次显示UIAlertController,从而创建一层UIAlerController,使背景变黑
我尝试了这个代码来解决这个问题,但没有成功
if (![topWindow.rootViewController.presentedViewController isKindOfClass:[UIAlertController class]]) {
[topWindow makeKeyAndVisible];
[topWindow.rootViewController presentViewController:uiAlert animated:YES completion:nil];
}
如果当前未显示UIAlertController,那么只显示一个UIAlertController的条件应该是什么?我建议不要这样做,从AppDelegate开始。绝对没有必要弄乱rootViewController
func checkIfAlertHasPresented() -> UIAlertController?
{
if var topController = UIApplication.sharedApplication().keyWindow?.rootViewController
{
while let presentedVC = topController.presentedViewController
{
topController = presentedVC
}
if topController is UIAlertController
{
return (topController as! UIAlertController)
}
else
{
return nil
}
}
return nil
}
建议的方法
为此,您可以采取两种方法:
-(void) showMessageWithHeader:(NSString *)header
andBody:(NSString *)bodyMessage{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:header message:bodyMessage preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction * okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
}];
[alertController addAction:okAction];
[self presentViewController:alertController animated: YES completion: nil];
}
您可以在从基础继承的任何ViewController中使用它,如下所示:
[self showMessageWithHeader:@"Alert"
andBody:@"This message was generated from base class"];
我个人推荐这种方法。您应该始终显示来自ViewController的消息,而不是某个管理器类。您可以使用块或任何东西将消息返回到ViewController,然后使用此方法显示消息
第二种方法:使用共享实用程序类。 但是,如果您更喜欢实用程序类方法(例如,如果您坚持直接显示来自manager类的消息,但显然不知道当前哪个ViewController可见),请添加一个实用程序类,让我们假设它称为UIUtilities。现在向其添加两个类方法:
+ (UIViewController *) getVisibleViewController{
UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
topController = [UIUtilities getVisibleViewControllerFrom:topController];
return topController;
}
+ (UIViewController *) getVisibleViewControllerFrom:(UIViewController *) vc {
if ([vc isKindOfClass:[UINavigationController class]]) {
return [UIUtilities getVisibleViewControllerFrom:[((UINavigationController *) vc) visibleViewController]];
} else if ([vc isKindOfClass:[UITabBarController class]]) {
return [UIUtilities getVisibleViewControllerFrom:[((UITabBarController *) vc) selectedViewController]];
} else {
if (vc.presentedViewController) {
return [UIUtilities getVisibleViewControllerFrom:vc.presentedViewController];
} else {
return vc;
}
}
}
使用+(UIViewController*)getVisibleViewController
将返回当前可见的ViewController。完成该部分后,现在可以添加类方法以在VisibleViewController上显示消息:
+(void) showMessageWithHeader:(NSString *)header
andBody:(NSString *)bodyMessage{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:header message:bodyMessage preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction * okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
}];
[alertController addAction:okAction];
if(![[UIUtilities getVisibleViewController] isKindOfClass:[UIAlertController class]]){
[[UIUtilities getVisibleViewController] presentViewController:alertController animated: YES completion: nil];
}
}
现在,您可以从任何希望显示以下消息的位置调用此方法:
[UIUtilities showMessageWithHeader:@"Alert"
andBody:@"This message came from Utility class"];
这将一次只显示一个警报。如果一个警报已可见,则不会显示其他警报。我不会这样做的,但既然那是你想要的,好吧
现在,无论您收到多少条消息,它们都会堆积在当前可见的ViewController上,您可以简单地逐个消除它们(或者根据需要,根据您采取的方法,一次只能看到一条警报),而无需任何额外的麻烦。这看起来非常有希望。我已经下班了,但我一到tmrw就会试试这个。我可能会使用第二种方法,因为消息将来自没有视图的类。