可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
This question already has answers here:
Closed 2 years ago.
I'm trying to present a UIAlertController
from the AppDelegate in my iOS app.
Below is the alert and the present method.
UIAlertController *alert = [UIAlertController alertControllerWithTitle:cTitle message:cMessage preferredStyle:UIAlertControllerStyleAlert];
//Configure alert and actions
[self.window.rootViewController presentViewController:alert animated:TRUE completion:nil];
However, when I try to present the alert, it doesn't appear and I get the following alert in the console.
Warning: Attempt to present <UIAlertController: 0x145f5d60> on <UINavigationController: 0x146590f0> whose view is not in the window hierarchy!
What is causing the error and how do I fix it?
回答1:
You can use this code as well if you want to launch it from didFinishLaunchingWithOptions.Hope this helps.
dispatch_async(dispatch_get_main_queue(), {
let importantAlert: UIAlertController = UIAlertController(title: "Action Sheet", message: "Hello I was presented from appdelegate ;)", preferredStyle: .ActionSheet)
self.window?.rootViewController?.presentViewController(importantAlert, animated: true, completion: nil)
})
回答2:
try this code..
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
NSLog(@"rakshapettu");
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"AlertView" message:@"I am an AlertView" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[alert dismissViewControllerAnimated:YES completion:nil];
}];
[alert addAction:defaultAction];
UIWindow *alertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
alertWindow.rootViewController = [[UIViewController alloc] init];
alertWindow.windowLevel = UIWindowLevelAlert + 1;
[alertWindow makeKeyAndVisible];
[alertWindow.rootViewController presentViewController:alert animated:YES completion:nil];
}
回答3:
It's better to use something like:
var hostVC = self.window?.rootViewController
while let next = hostVC?.presentedViewController {
hostVC = next
}
hostVC?.presentViewController(alertController, animated: true, completion: nil)
Previous answers won't work if you are already presenting modal view controller.
回答4:
you call it before the window is up and the navigationController is actually shown:
"Warning: Attempt to present on whose view is not in the window hierarchy!"
likely you do so in applicationDidFinishLaunching?
EITHER wait .. like do it when the view really appears
OR
one 'hack' would be to force the view and window up yourself:
[self.window addSubview:self.rootViewController.view];
[self.window makeKeyAndVisible];
回答5:
I was trying the same but does not work because after change of viewcontroller still returned the initial viewcontroller and throw the error whose view is not in the window hierarchy!
. Finally, I found the solution to this problem:
UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(alertController, animated: true, completion: nil)
But I have to force view controllers to update de keyWindow
with this:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
UIApplication.sharedApplication().keyWindow!.rootViewController = self
UIApplication.sharedApplication().keyWindow!.makeKeyAndVisible()
}
回答6:
You can try calling it in viewDidAppear
instead of viewDidLoad
. I had a similar error and that fixed it.
回答7:
Using Alert Controller:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
dispatch_async(dispatch_get_main_queue(), {
//INTERNET NOT AVAILABLE ALERT
var internetUnavailableAlertController = UIAlertController (title: "Network Unavailable", message: "Please check your internet connection settings and turn on Network Connection", preferredStyle: .Alert)
var settingsAction = UIAlertAction(title: "Settings", style: .Default) { (_) -> Void in
let settingsUrl = NSURL(string: UIApplicationOpenSettingsURLString)
if let url = settingsUrl {
UIApplication.sharedApplication().openURL(url)
}
}
var cancelAction = UIAlertAction(title: "Okay", style: .Default, handler: nil)
internetUnavailableAlertController .addAction(settingsAction)
internetUnavailableAlertController .addAction(cancelAction)
self.window?.rootViewController!.presentViewController(internetUnavailableAlertController , animated: true, completion: nil)
})
Using AlertView:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
dispatch_async(dispatch_get_main_queue(), {
//INTERNET NOT AVAILABLE ALERTVIEW
let internetUnavailableAlert = UIAlertView(title: "Network Unavailable", message: "Please check your internet connection settings and turn on Network Connection", delegate: self, cancelButtonTitle: "Okay")
internetUnavailableAlert.show()
})
return true
}
}