UIAlertController 未从 AppDelegate 显示

UIAlertController not showing from AppDelegate

我正在尝试像这样在全局范围内(从不是视图控制器的地方)显示 UIAlertController,但我的警报没有显示。我正在测试我的初始警报,该警报在检测到无网络后由 App Delegate 中的可达性测试显示。我可以在屏幕上看到启动图像,但未显示警报。如果我使用 UIAlertView,一切看起来都不错。

如有遇到类似问题请指教

UIAlertController *alert = [UIAlertController alertControllerWithTitle:iTitle message:iMessage preferredStyle:UIAlertControllerStyleAlert];
id rootViewController = [UIApplication sharedApplication].delegate.window.rootViewController;

if ([rootViewController isKindOfClass:[UINavigationController class]]) {
   rootViewController = [((UINavigationController *)rootViewController).viewControllers objectAtIndex:0];
}

dispatch_async(dispatch_get_main_queue(), ^{
    [rootViewController presentViewController:alert animated:YES completion:^{
        [aBlockSelf alertPresented];
    }];
});

编辑:

为什么我要从 AppDelegate 显示它?

正如我所说,我在执行可达性测试后立即向用户显示警报。这个测试必须在 AppDelegate 内执行,甚至在我加载任何视图控制器之前。因此,我在我的 UIWindow 上显示了启动画面,我希望我的警报出现在它上面。

当我显示警报时,我的 window 设置是否正确?

是的,我确保我的警报控制器 post window 已正确设置,并且在执行以下行后!

[self.window addSubview:self.rootViewController.view];
[self.window makeKeyAndVisible];

设置Rootviewcontroller而不是添加子视图

   [self.window setRootViewController: self.rootViewController];

从视图控制器发送包含您当前视图控制器的通知:

[[NSNotificationCenter defaultCenter] postNotificationName:@"ShowAlertNotificationKey"
                                                        object:self
                                                      userInfo:nil];

在您的 AppDelegate 中添加一个观察者:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(showAlert:)
                                             name:@"ShowAlertNotificationKey"
                                           object:nil];

以及将呈现 AlertController 的方法:

- (void)showAlert:(NSNotification *)notification {
    UIViewController *viewController = notification.object;
    // yourAlertControler..
    [viewController presentViewController:yourAlertController animated:YES completion:nil];
}

好吧,我通过创建一个带有空视图控制器的 UIWindow object 并在其中显示我的警报来解决这个问题。显然,一旦警报控制器被解除,这个临时 window 也会消失。

self.alertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.alertWindow.rootViewController = [[UIViewController alloc] init];
self.alertWindow.windowLevel = UIWindowLevelAlert + 1;
[self.alertWindow makeKeyAndVisible];
[self.alertWindow.rootViewController presentViewController:alertControl animated:YES completion:^{
    [aBlockSelf alertPresented];
}];

感谢 this SO thread 提到了 WWDC 实验室 session :-)!

对于 swift 3.0 这将有效 -

let topWindow = UIWindow(frame: UIScreen.main.bounds)  
topWindow.rootViewController = UIViewController()             
topWindow.windowLevel = UIWindowLevelAlert + 1

let alert = UIAlertController(title: "No Network Connection", message:   "Please check your connection and try again.", preferredStyle: .alert)

alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: {(_ action: UIAlertAction) -> Void in

     topWindow.isHidden = true
}))
topWindow.makeKeyAndVisible()
topWindow.rootViewController?.present(alert, animated: true, completion: { _ in })