Present UIAlertController from AppDelegate

来源:互联网 发布:学java最好的学 编辑:程序博客网 时间:2024/06/05 05:00


转自:http://stackoverflow.com/questions/26952061/present-uialertcontroller-from-appdelegate



up vote17down votefavorite
3

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?

shareimprove this question
 
 
Trying to present right as the app is launching I'm guessing? – Acey Nov 16 '14 at 0:33 
 
Can you try this link for usefull Link: [ alertViewController](stackoverflow.com/a/37029075/2442762) – joel prithivi May 4 at 13:25 

8 Answers

activeoldestvotes
up vote13down vote

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)        })
shareimprove this answer
 
 
Hi @AdiQuadCore, your is useful only in swift application. In objC, the UIAlertController needs a pointer to the current UIViewController. – Zeb Sep 16 '15 at 12:22
 
This worked for me in ObjC in didFinishLaunchingWithOptions – Seoras Oct 6 at 5:04
up vote5down vote

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];
shareimprove this answer
 
up vote5down vote

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]; }
shareimprove this answer
 
up vote3down vote

It's better to use something like:

var hostVC = self.window?.rootViewControllerwhile 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.

shareimprove this answer
 
 
Perfect answer and a really good method to handle modally presented view controllers! Thanks! – NerdyTherapist 2 days ago
up vote2down vote

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()}
shareimprove this answer
 
up vote1down vote

You can try calling it in viewDidAppear instead of viewDidLoad. I had a similar error and that fixed it.

shareimprove this answer
 
up vote-1down vote

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 }}
shareimprove this answer
 
up vote-3down vote

You are trying to present UIAlertController on UINavigationController, which appeared to be your rootViewController and the problem is you cannot present UIAlertController on UINavigationController, the UIAlertController needs a view controller's from which it can be presented.

Can you not call as follow,

[self presentViewController:alert animated:YES completion:nil];

here self refers to current view controller, on which you are presenting the alert.

shareimprove this answer
 
 
thats not really what the message says though. and a navigationController is a viewController and it also has a view IF visible – Daij-Djan Nov 16 '14 at 0:44
 
Correct me if I am wrong, the UINavigationController class implements a specialized view controller that manages the navigation of hierarchical content so you cannot present any UIAlertController from it? – ldinduNov 16 '14 at 0:52

0 0
原创粉丝点击