UIAlertController – Acción no ejecutada si se desestimó la alerta la primera vez

En un proyecto en el que estoy trabajando, tuve que escribir un module auxiliar de UIAlert que mostraría windows emergentes aquí y allá en mi aplicación iOS. Las windows emergentes se escriben como funciones de class que simplemente puedo llamar a cualquier parte del código (la class es estática y también lo son todas las funciones).

Ahora estoy encontrando un error muy extraño en el que si descartas una alerta una vez, luego la abres otra vez, sus acciones ya no funcionan (como en el manejador de acciones no se llama). Funciona si hace clic en la acción la primera vez que se muestra la window emergente, aunque …

Aquí está el código de la window emergente específica para el que se produce este error (no hay otros popups afectados de ninguna manera):

static func popSkipWalkthrough() { let alert = UIAlertController(title: "Skip", message: "whatever", prefernetworkingStyle: .Alert) alert.addAction(cancelAction) alert.addAction(skipWalkthroughAction) appDelegate.window!.rootViewController!.presentViewController(alert, animated: true, completion: nil) } 

El skipWalkthroughAction se define de la siguiente manera:

 static let skipWalkthroughAction = UIAlertAction(title: "Continue", style: .Default, handler: { (action: UIAlertAction!) -> Void in appDelegate.setWindowViewTo("NavCtrl", navigateTo: false) CallIn.Settings.didWalkthrough = true }) 

Y cancelAction se define como:

 static let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil) 

Esta window emergente, en particular, se muestra cada vez que presiona el button "omitir" en el último paso de un recorrido …

He intentado algunos consejos sobre cuál es la causa de este comportamiento, y creo que podría tener algo que ver con que la window emergente no esté realmente desasignada, pero no estoy seguro en absoluto en este momento …

Algunas ideas ?

Aunque tengo problemas con la forma en que esta pieza reutilizable está codificada, este problema se puede resolver enviando un post copy: skipWalkthroughAction . Simplemente haz a:

 static func popSkipWalkthrough() { let alert = UIAlertController(title: "Skip", message: "whatever", prefernetworkingStyle: .Alert) alert.addAction(cancelAction.copy() as! UIAlertAction) alert.addAction(skipWalkthroughAction.copy() as! UIAlertAction) appDelegate.window!.rootViewController!.presentViewController(alert, animated: true, completion: nil) } 

Esto debería solucionarlo.

También puede resolver esto moviendo la alert al nivel de instancia. No tiene que enviar copy: entonces.

Mejor enfoque

Si desea una experiencia "verdaderamente" reutilizable de UIAlertController , es mejor crear una extensión UIViewController . Tengo esto en uno de mis proyectos:

 extension UIViewController { func showAlertControllerWithTitle(title:String?,message:String?,actions:[UIAlertAction],dismissingActionTitle:String?, dismissBlock:(() -> ())?) -> UIAlertController { let alertController = UIAlertController(title: title, message: message, prefernetworkingStyle: .Alert) if dismissingActionTitle != nil { let okAction = UIAlertAction(title: dismissingActionTitle, style: .Default) { (action) -> Void in dismissBlock?() alertController.dismissViewControllerAnimated(true, completion:nil) } alertController.addAction(okAction) } for action in actions { alertController.addAction(action) } self.presentViewController(alertController, animated: true, completion:nil) return alertController } }