Joakim
Joakim

Reputation: 3294

Method showing alert in App Delegate fails because it's rootViewController is not in the View Hierarcy

During development of my iOS application, I would like to be able to show the user a dialog if a serious bug occurs.

on SO, found that this could be achieved with adding something like the following to my AppDelegate class

- (void) notifyUserAboutSeriousBugWithMessage:(NSString *)message {
    UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Serious bug: Alert developer"
                                                                   message:message
                                                            preferredStyle:UIAlertControllerStyleAlert];

    UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"Continue" style:UIAlertActionStyleDefault
                                                          handler:^(UIAlertAction * action) {}];
    [alert addAction:defaultAction];

    [self.window.rootViewController presentViewController:alert animated:YES completion:^{}];
}

However, when I run this, i get an error message saying I'm Attempting to present <A> on <B> whose view is not in the window hierarchy!

My application is using a storyboard and the Entry/Start point <B> is a Splash Screen (-viewController). [This is not contained in a NavigationController]

When I'm done with the splash screen, I use a Modal Segue to show "the rest" of the app.

So how can I workaround this? In my app delegate, I want to get some view controller that will be in the view hierarcy and show my Alert in it's view.

(The reason I want to put this in the app delegate is that I want to present error alerts from classes that are not view controllers)

Thanks!

Upvotes: 0

Views: 395

Answers (1)

deadbeef
deadbeef

Reputation: 5563

That's probably because you already have a presented viewController on top of your rootViewController. You need to present your alert on top of the topmost view controller.

Here is how you can get the topmost controller :

UIViewController *topViewController = self.window.rootViewController;
while (topViewController.presentedViewController) {
    topViewController = topViewController.presentedViewController;
}

You can then do :

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

Upvotes: 1

Related Questions