web-dev-qa-db-fra.com

Comment présenter UIAlertView depuis appDelegate

J'essaie d'afficher un UIAlertView à partir de l'appDelegate dans didReceiveRemoteNotification lorsque l'application reçoit une notification Push.

J'ai cette erreur: 

  Warning: Attempt to present <UIAlertController: 0x14c5494c0> on <UINavigationController:
  0x14c60ce00> whose view is not in the window hierarchy!

voici mon code:

func application(application: UIApplication, didReceiveRemoteNotification userInfo: NSDictionary) {

    var contentPush: NSDictionary = userInfo.objectForKey("aps") as NSDictionary

    var message = contentPush.objectForKey("alert") as String



    let alertController = UIAlertController(title: "Default Style", message: message, preferredStyle: .Alert)

    let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { (action) in
                    // ...
    }
    alertController.addAction(cancelAction)

    let OKAction = UIAlertAction(title: "OK", style: .Default) { (action) in

        let photoPushedVc = self.storyboard.instantiateViewControllerWithIdentifier("CommentTableViewController") as CommentTableViewController

        println("the fetched post is \(post)")

        photoPushedVc.post = post

        let activeVc = UIApplication.sharedApplication().keyWindow?.rootViewController

        activeVc?.presentViewController(photoPushedVc, animated: true, completion: nil)
   }

   alertController.addAction(OKAction)

   let activeVc = UIApplication.sharedApplication().keyWindow?.rootViewController


   activeVc?.presentViewController(alertController, animated: true, completion: nil)}
13
jmcastel

Ok, j'ai enfin compris, vous devez trouver le VC actif en utilisant ceci avant d'essayer de présenter votre alertController:

let navigationController = application.windows[0].rootViewController as UINavigationController
let activeViewCont = navigationController.visibleViewController
activeViewCont.presentViewController(alertController, animated: true, completion: nil)
12
jmcastel

Pour générer AlertController Boîte de dialogue à partir de AppDelegate using Objective-C ,

UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Title" message:@"Hello World!" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:ok];

Type 1

UIWindow *alertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
alertWindow.rootViewController = [[UIViewController alloc] init];
alertWindow.windowLevel = UIWindowLevelAlert + 1;
[alertWindow makeKeyAndVisible];
[alertWindow.rootViewController presentViewController:alertController animated:YES completion:nil];

Type 2

UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (topController.presentedViewController) {
    topController = topController.presentedViewController;
}
[topController presentViewController:alertController animated:YES completion:nil];

Les deux sont testés et fonctionnent bien.

15
computingfreak

Voici le mien exemple Swift 3.0

func showTopLevelAlert() {
    let alertController = UIAlertController (title: "title", message: "message.", preferredStyle: .alert)

    let firstAction = UIAlertAction(title: "First", style: .default, handler: nil)
    alertController.addAction(firstAction)

    let cancelAction = UIAlertAction(title: "Отмена", style: .cancel, handler: nil)
    alertController.addAction(cancelAction)

    let alertWindow = UIWindow(frame: UIScreen.main.bounds)

    alertWindow.rootViewController = UIViewController()
    alertWindow.windowLevel = UIWindowLevelAlert + 1;
    alertWindow.makeKeyAndVisible()

    alertWindow.rootViewController?.present(alertController, animated: true, completion: nil)

}

J'espère que ça aide à quelqu'un 

9
Nosov Pavel

Si vous avez besoin de la même chose dans Objective-c

UIAlertController *alertvc = [UIAlertController alertControllerWithTitle:@"Alert Title..!!" message:@"Hey! Alert body come here." preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *actionOk = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {

}];

[alertvc addAction:actionOk];
  1. Si vous avez une application basée sur la navigation:

    UINavigationController *nvc = (UINavigationController *)[[application windows] objectAtIndex:0].rootViewController;
    UIViewController *vc = nvc.visibleViewController;
    [vc presentViewController:alertvc animated:YES completion:nil];
    
  2. Si vous avez une application basée sur une seule vue:

    UIViewController *vc = self.window.rootViewController;
    [vc presentViewController:alertvc animated:YES completion:nil];
    
6
umakanta

Pour afficher une alerte sur le contrôleur supérieur du délégué de l'application

var topController : UIViewController = (application.keyWindow?.rootViewController)!

    while ((topController.presentedViewController) != nil) {
        topController = topController.presentedViewController!
    }

    //showAlertInViewController func is in UIAlertController Extension
    UIAlertController.showAlertInViewController(topController, withMessage: messageString, title: titleString)

Ajouter une extension dans UIAlertController

    static func showAlertInViewController(viewController: UIViewController?, withMessage message: String, title: String) {
    let myAlert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)

    myAlert.addAction(UIAlertAction(title: NSLocalizedString("Ok", comment: ""), style: .Default, handler: { (action: UIAlertAction!) in
        print("Handle Ok logic here")

        // Let the alert simply dismiss for now
    }))

    viewController?.presentViewController(myAlert, animated: true, completion: nil)
}
0
Mohsin Qureshi

J'utilise une extension UIViewController pour obtenir le contrôleur de vue visible actuel (voir: Comment obtenir viewController visible à partir d'un délégué d'application lors de l'utilisation du storyboard? ).

puis présentez le contrôleur d'alerte: 

let visibleVC = UIApplication.sharedApplication().keyWindow?.rootViewController?.visibleViewController
visibleVC!.presentViewController(alertController, animated: true, completion: nil)
0
MrRhoads