tutorial notification apple ios swift uialertcontroller

apple - push notifications in ios



Mostrar alerta en AppDelegate en Swift (8)

Esta pregunta ya tiene una respuesta aquí:

Intento el siguiente fragmento de código:

var alert = UIAlertController(title: "Alert", message: "Cannot connect to : /(error!.localizedDescription)", preferredStyle: UIAlertControllerStyle.Alert) alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.Default, handler: nil)) self.window?.rootViewController?.presentViewController(alert, animated: true, completion: nil)

en mi AppDelegate, pero me imprime el siguiente error en la consola:

Warning: Attempt to present <UIAlertController: 0x7ff6cd827a30> on <Messenger.WelcomeController: 0x7ff6cb51c940> whose view is not in the window hierarchy!

¿Cómo puedo solucionar este error?


¿Ha intentado usar UIApplication.shared.keyWindow?.rootViewController?.present(...) ?


Esto es lo que estoy usando ahora para hacer eso.

var alertController = UIAlertController(title: "Title", message: "Any message", preferredStyle: .ActionSheet) var okAction = UIAlertAction(title: "Yes", style: UIAlertActionStyle.Default) { UIAlertAction in NSLog("OK Pressed") } var cancelAction = UIAlertAction(title: "No", style: UIAlertActionStyle.Cancel) { UIAlertAction in NSLog("Cancel Pressed") } alertController.addAction(okAction) alertController.addAction(cancelAction) self.window?.rootViewController?.presentViewController(alertController, animated: true, completion: nil)


SWIFT 3

let alert = UIAlertController(title: "Test", message:"Message", preferredStyle: UIAlertControllerStyle.alert) // add an action (button) alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil)) // show the alert self.window?.rootViewController?.present(alert, animated: true, completion: nil)


Según la respuesta de Jorge, actualizada para Swift 4

let alertController = UIAlertController(title: "Title", message: "Message", preferredStyle: .actionSheet) let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default) { UIAlertAction in NSLog("OK Pressed") } let cancelAction = UIAlertAction(title: "CANCEL", style: UIAlertActionStyle.cancel) { UIAlertAction in NSLog("Cancel Pressed") } alertController.addAction(okAction) alertController.addAction(cancelAction) self.window?.rootViewController?.present(alertController, animated: true, completion: nil)


Supongo que está llamando a ese fragmento de código desde la aplicaciónDidFinishLunchingWithOptions:. Lo intenté de hecho porque tenía que hacerlo. El problema es que lo que intentas hacer es correcto, pero el ViewController que crea y presenta el AppDelegate está a punto de aparecer en pantalla y, antes de eso, el fragmento de código intenta crear un alertView y colocarlo encima de un view no existente de el RootViewController.

Lo que haría es moverlo a otra llamada de delegado que se garantiza que se llamará después de que se presente el RootViewController.

func applicationDidBecomeActive(application: UIApplication) { //This method is called when the rootViewController is set and the view. // And the View controller is ready to get touches or events. var alert = UIAlertController(title: "Alert", message: "Cannot connect to :", preferredStyle: UIAlertControllerStyle.Alert) alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.Default, handler: nil)) self.window?.rootViewController?.presentViewController(alert, animated: true, completion: nil) }

Pero como siempre sabemos la responsabilidad de la AppDelegate. Es para manejar el ciclo de vida de la aplicación y las llamadas y eventos delegados en toda la aplicación. Si poner código aquí tiene sentido, entonces hazlo. Pero si le conviene más poner el código en el controlador de control rootView o en otras partes, piénselo también.

De todos modos, espero que ayude. ¡Aclamaciones!


Swift 3.0 o superior, trabajando en todas las condiciones, como en el caso de la barra de pestañas, en el caso de la vista presentada, etc.

let alert = UIAlertController(title: "Test", message:"Message", preferredStyle: UIAlertControllerStyle.alert) // add an action (button) alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil)) // show alert let alertWindow = UIWindow(frame: UIScreen.main.bounds) alertWindow.rootViewController = UIViewController() alertWindow.windowLevel = UIWindowLevelAlert + 1; alertWindow.makeKeyAndVisible() alertWindow.rootViewController?.present(alertController, animated: true, completion: nil)


Tuve el problema similar.

Lo arreglé presentando UIAlertController en Main Queue .

El código parece seguir.

let alert = UIAlertController(title: "My Title", message: "My Message", preferredStyle: .alert) let actionYes = UIAlertAction(title: "Yes", style: .default, handler: { action in print("action yes handler") }) let actionCancel = UIAlertAction(title: "Cancel", style: .destructive, handler: { action in print("action cancel handler") }) alert.addAction(actionYes) alert.addAction(actionCancel) DispatchQueue.main.async { self.window?.rootViewController?.present(alert, animated: true, completion: nil) }


Yo sugeriría NO hacer esto en el AppDelegate. El delegado de la aplicación tenía la intención de manejar las funciones del delegado desde el sistema operativo en lugar de implementar cosas como vistas de alerta.

Si desea presentar una vista de alerta aquí para que se muestre al inicio de la aplicación, lo haría implementándolo en su primer controlador de vista.