1

I am trying to present an UIAlertController globally (from a place which is not a view controller) like this but my alert does not show up. I am testing my initial alert which is shown by reachability test in App Delegate after detecting no network. I can see launch image on my screen but alert does not show up. If I use UIAlertView, everything looks good.

If you had encountered similar issue then please advise.

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];
    }];
});

EDIT:

Why am I showing it from AppDelegate?

As I said, I am showing an alert to user as soon as I execute my reachability test. This test has to be performed from within AppDelegate even before I load any view controller. So, I show a splash screen on my UIWindow and I am expecting my alert to come on top of it.

Is my window set up correctly when I present the alert?

Yes, I am ensuring that I present alert controller post window is correctly set and that after below lines are executed!

[self.window addSubview:self.rootViewController.view];
[self.window makeKeyAndVisible];
Abhinav
  • 37,684
  • 43
  • 191
  • 309

4 Answers4

4

Alright, I solved this problem by creating a UIWindow object with an empty view controller and presenting my alert in it. Apparently, once alert controller is dismissed, this temporary window also go away.

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];
}];

Thanks to this SO thread where a WWDC lab session is referred :-)!

Community
  • 1
  • 1
Abhinav
  • 37,684
  • 43
  • 191
  • 309
1

From the view controller, send a notification that contains your current view controller:

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

Add an observer in your AppDelegate:

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

And the method that will present the AlertController:

- (void)showAlert:(NSNotification *)notification {
    UIViewController *viewController = notification.object;
    // yourAlertControler..
    [viewController presentViewController:yourAlertController animated:YES completion:nil];
}
Kenan Karakecili
  • 731
  • 6
  • 23
1

For swift 3.0 this will work -

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 })
ravi sendhav
  • 177
  • 10
0

Set Rootviewcontroller insted of adding subview

   [self.window setRootViewController: self.rootViewController];
Sunny Shah
  • 12,990
  • 9
  • 50
  • 86