猿问
下载APP

如何在没有视图控制器的情况下显示UIAlertController?

如何在没有视图控制器的情况下显示UIAlertController?

场景:用户点击视图控制器上的按钮。视图控制器是导航堆栈中的最顶层(显然)。TAP调用另一个类上调用的实用程序类方法。在那里发生了一件坏事,我想在控件返回到视图控制器之前在那里显示一个警告。

+ (void)myUtilityMethod {
    // do stuff
    // something bad happened, display an alert.}

这是有可能的UIAlertView(但可能不太恰当)。

在这种情况下,您如何表示UIAlertController,就在那里myUtilityMethod?


PIPIONE
浏览 94回答 3
3回答

慕慕森

在WWDC,我在其中一个实验室停了下来,问了一个苹果工程师同样的问题:“展示一个UIAlertController?“他说他们经常听到这个问题,我们开玩笑说他们应该就此举行一次会议。他说,苹果公司内部正在创造一个UIWindow透明的UIViewController然后展示UIAlertController在上面。基本上迪伦·贝特曼的答案是什么。但我不想使用UIAlertController因为这需要我在整个应用程序中修改我的代码。因此,在关联对象的帮助下,我在UIAlertController提供了一个show方法的目标-C。以下是相关代码:#import&nbsp;"UIAlertController+Window.h"#import&nbsp;<objc/runtime.h>@interface&nbsp;UIAlertController&nbsp;(Window)-&nbsp;(void)show;-&nbsp;(void)show:(BOOL)animated;@end@interface&nbsp;UIAlertController&nbsp;(Private)@property&nbsp;(nonatomic,&nbsp;strong)&nbsp;UIWindow&nbsp;*alertWindow;@end@implementation&nbsp;UIAlertController&nbsp;(Private)@dynamic&nbsp;alertWindow;-&nbsp;(void)setAlertWindow:(UIWindow&nbsp;*)alertWindow&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;objc_setAssociatedObject(self,&nbsp;@selector(alertWindow),&nbsp;alertWindow,&nbsp;OBJC_ASSOCIATION_RETAIN_NONATOMIC);}-&nbsp;(UIWindow&nbsp;*)alertWindow&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;objc_getAssociatedObject(self,&nbsp;@selector(alertWindow));}@end@implementation&nbsp;UIAlertController&nbsp;(Window)-&nbsp;(void)show&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;[self&nbsp;show:YES];}-&nbsp;(void)show:(BOOL)animated&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;self.alertWindow&nbsp;=&nbsp;[[UIWindow&nbsp;alloc]&nbsp;initWithFrame:[UIScreen&nbsp;mainScreen].bounds]; &nbsp;&nbsp;&nbsp;&nbsp;self.alertWindow.rootViewController&nbsp;=&nbsp;[[UIViewController&nbsp;alloc]&nbsp;init]; &nbsp;&nbsp;&nbsp;&nbsp;id<UIApplicationDelegate>&nbsp;delegate&nbsp;=&nbsp;[UIApplication&nbsp;sharedApplication].delegate; &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Applications&nbsp;that&nbsp;does&nbsp;not&nbsp;load&nbsp;with&nbsp;UIMainStoryboardFile&nbsp;might&nbsp;not&nbsp;have&nbsp;a&nbsp;window&nbsp;property: &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;([delegate&nbsp;respondsToSelector:@selector(window)])&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;we&nbsp;inherit&nbsp;the&nbsp;main&nbsp;window's&nbsp;tintColor &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.alertWindow.tintColor&nbsp;=&nbsp;delegate.window.tintColor; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;window&nbsp;level&nbsp;is&nbsp;above&nbsp;the&nbsp;top&nbsp;window&nbsp;(this&nbsp;makes&nbsp;the&nbsp;alert,&nbsp;if&nbsp;it's&nbsp;a&nbsp;sheet,&nbsp;show&nbsp;over&nbsp;the&nbsp;keyboard) &nbsp;&nbsp;&nbsp;&nbsp;UIWindow&nbsp;*topWindow&nbsp;=&nbsp;[UIApplication&nbsp;sharedApplication].windows.lastObject; &nbsp;&nbsp;&nbsp;&nbsp;self.alertWindow.windowLevel&nbsp;=&nbsp;topWindow.windowLevel&nbsp;+&nbsp;1; &nbsp;&nbsp;&nbsp;&nbsp;[self.alertWindow&nbsp;makeKeyAndVisible]; &nbsp;&nbsp;&nbsp;&nbsp;[self.alertWindow.rootViewController&nbsp;presentViewController:self&nbsp;animated:animated&nbsp;completion:nil];}-&nbsp;(void)viewDidDisappear:(BOOL)animated&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;[super&nbsp;viewDidDisappear:animated]; &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;precaution&nbsp;to&nbsp;ensure&nbsp;window&nbsp;gets&nbsp;destroyed &nbsp;&nbsp;&nbsp;&nbsp;self.alertWindow.hidden&nbsp;=&nbsp;YES; &nbsp;&nbsp;&nbsp;&nbsp;self.alertWindow&nbsp;=&nbsp;nil;}@end下面是一个示例用法://&nbsp;need&nbsp;local&nbsp;variable&nbsp;for&nbsp;TextField&nbsp;to&nbsp;prevent&nbsp;retain&nbsp;cycle&nbsp;of&nbsp;Alert&nbsp;otherwise&nbsp;UIWindow//&nbsp;would&nbsp;not&nbsp;disappear&nbsp;after&nbsp;the&nbsp;Alert&nbsp;was&nbsp;dismissed__block&nbsp;UITextField&nbsp;*localTextField;UIAlertController&nbsp;*alert&nbsp;=&nbsp;[UIAlertController&nbsp;alertControllerWithTitle:@"Global&nbsp;Alert"&nbsp;message:@"Enter&nbsp;some&nbsp;text"&nbsp;preferredStyle:UIAlertControllerStyleAlert];[alert&nbsp;addAction:[UIAlertAction&nbsp;actionWithTitle:@"OK"&nbsp;style:UIAlertActionStyleDefault&nbsp;handler:^(UIAlertAction&nbsp;*action)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;NSLog(@"do&nbsp;something&nbsp;with&nbsp;text:%@",&nbsp;localTextField.text);//&nbsp;do&nbsp;NOT&nbsp;use&nbsp;alert.textfields&nbsp;or&nbsp;otherwise&nbsp;reference&nbsp;the&nbsp;alert&nbsp;in&nbsp;the&nbsp;block.&nbsp;Will&nbsp;cause&nbsp;retain&nbsp;cycle}]];[alert&nbsp;addTextFieldWithConfigurationHandler:^(UITextField&nbsp;*textField)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;localTextField&nbsp;=&nbsp;textField;}];[alert&nbsp;show];这个UIWindow时,所创建的数据将被销毁。UIAlertController,因为它是唯一保留UIWindow..但是如果您指定UIAlertController属性或通过访问一个操作块中的警报使其保留计数增加,UIWindow会留在屏幕上,锁定你的UI。在需要访问的情况下,请参阅上面的示例使用代码以避免UITextField.我用一个测试项目做了一个GitHub回购:FFGlobalAlertController

BIG阳

您可以使用SWIFT 2.2执行以下操作:let&nbsp;alertController:&nbsp;UIAlertController&nbsp;=&nbsp;...UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(alertController,&nbsp;animated:&nbsp;true,&nbsp;completion:&nbsp;nil)以及SWIFT 3.0:let&nbsp;alertController:&nbsp;UIAlertController&nbsp;=&nbsp;...UIApplication.shared.keyWindow?.rootViewController?.present(alertController,&nbsp;animated:&nbsp;true,&nbsp;completion:&nbsp;nil)

梵蒂冈之花

斯威夫特let&nbsp;alertController&nbsp;=&nbsp;UIAlertController(title:&nbsp;"title",&nbsp;message:&nbsp;"message",&nbsp;preferredStyle:&nbsp;.alert)//...var&nbsp;rootViewController&nbsp;=&nbsp;UIApplication.shared.keyWindow?.rootViewControllerif&nbsp;let&nbsp;navigationController&nbsp;=&nbsp;rootViewController&nbsp;as?&nbsp;UINavigationController&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;rootViewController&nbsp;=&nbsp;navigationController.viewControllers.first}if&nbsp;let&nbsp;tabBarController&nbsp;=&nbsp;rootViewController&nbsp;as?&nbsp;UITabBarController&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;rootViewController&nbsp;=&nbsp;tabBarController.selectedViewController}//...rootViewController?.present(alertController,&nbsp;animated:&nbsp;true,&nbsp;completion:&nbsp;nil)目标-CUIAlertController&nbsp;*alertController&nbsp;=&nbsp;[UIAlertController&nbsp;alertControllerWithTitle:@"Title"&nbsp;message:@"message"&nbsp;preferredStyle:UIAlertControllerStyleAlert];//...id&nbsp;rootViewController&nbsp;=&nbsp;[UIApplication&nbsp;sharedApplication].delegate.window.rootViewController;if([rootViewController&nbsp;isKindOfClass:[UINavigationController&nbsp;class]]){ &nbsp;&nbsp;&nbsp;&nbsp;rootViewController&nbsp;=&nbsp;((UINavigationController&nbsp;*)rootViewController).viewControllers.firstObject;}if([rootViewController&nbsp;isKindOfClass:[UITabBarController&nbsp;class]]){ &nbsp;&nbsp;&nbsp;&nbsp;rootViewController&nbsp;=&nbsp;((UITabBarController&nbsp;*)rootViewController).selectedViewController;}//...[rootViewController&nbsp;presentViewController:alertController&nbsp;animated:YES&nbsp;completion:nil];
打开App,查看更多内容
随时随地看视频慕课网APP
我要回答