2015-03-31 1 views
0

Le problème en question concerne un AddItemView qui est présenté de manière modale par son délégué et contient une tableView. Lorsque l'utilisateur sélectionne un élément de tableView, il déclenche une action sur le délégué. En fonction de la réponse du serveur, le délégué peut présenter une autre vue modale ou une UIAlertView au-dessus du modal courant.Présente UIAlertView du délégué actuel du modal

Remarque importante: Cette UIAlertView doit être présentée lorsque le modal est toujours à l'écran. La vue modale présentée contenant tableView ne peut pas être ignorée après la sélection de l'utilisateur, car l'utilisateur doit pouvoir sélectionner plusieurs éléments de la table et, un par un, les renvoyer au délégué pour traitement.

Actuellement, l'UIAlerView n'est pas affiché et je suppose que c'est parce que le modal déjà présenté l'empêche. Existe-t-il une solution de contournement pour présenter le UIAlertView du délégué lorsque le délégué est assis sous un modal et sans rejeter ce modal?

Le UIAlertView est affiché comme tant par le délégué, tandis que le délégué est assis sous un modal:

var alert = UIAlertController(title: "Error", message: "Error message from server", preferredStyle: UIAlertControllerStyle.Alert) 

    alert.addAction(UIAlertAction(title: "actionOne", style: .Default, handler: { action in 
    // perform some action 

    })) 

    alert.addAction(UIAlertAction(title: "actionTwo", style: .Destructive, handler: { action in 
    // perform some action 

    })) 

    self.presentViewController(alert, animated: true, completion: nil) 

Voici l'erreur qui est renvoyée lorsque le UIAlertView est présenté par le délégué:

Warning: Attempt to present <UIAlertController: 0x156da6300> on <productionLINK_Scanner.ContainerContents: 0x156e65b20> whose view is not in the window hierarchy! 

Si possible, veuillez fournir une réponse en utilisant Swift.

+0

Où exactement dans la vie du contrôleur essayez-vous de présenter le contrôleur d'alerte? Il n'y a aucun problème à présenter un contrôleur au-dessus d'un autre. En outre, vous n'avez pas besoin de fermer le contrôleur d'alerte dans vos gestionnaires, il est automatiquement ignoré. –

+0

@LeoNatan UIAlertView est présenté à partir du délégué lorsqu'un utilisateur sélectionne une ligne dans le tableauView de modal présenté. Il est important de noter que le tableauView présenté de façon modale (c'est en fait un tableauView intégré dans un UIView) doit rester à l'écran - il ne peut pas être ignoré car l'utilisateur doit pouvoir sélectionner plusieurs éléments de la table et renvoyer chacun au délégué. –

Répondre

1

Résolu:

Utilisé l'extension suivante, grâce à yonat sur GitHub:

extension UIApplication { 

    class func topViewController(base: UIViewController? = UIApplication.sharedApplication().keyWindow?.rootViewController) -> UIViewController? { 
     if let nav = base as? UINavigationController { 
      return topViewController(base: nav.visibleViewController) 
     } 
     if let tab = base as? UITabBarController { 
      if let selected = tab.selectedViewController { 
       return topViewController(base: selected) 
      } 
     } 
     if let presented = base?.presentedViewController { 
      return topViewController(base: presented) 
     } 
     return base 
    } 
} 

Dans le délégué en question, il a été mis en œuvre comme ceci:

var alert = UIAlertController(title: "Alert Title", message: "Message Body", preferredStyle: UIAlertControllerStyle.Alert) 

alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: { action in 

})) 

if let topController = UIApplication.topViewController(base: self) { 
    topController.presentViewController(alert, animated: true, completion: nil) 

} else { 
    // If all else fails, attempt to present the alert from this controller. 
    self.presentViewController(alert, animated: true, completion: nil) 

} 

Cela permet maintenant le processus suivant:

  1. ContainerView est chargé en tant que délégué de ItemTableView
  2. utilisateur clique searchButton
  3. ContainerView présente modalement une liste d'articles ItemTableView
  4. chaque fois qu'une utilisation sélectionne une ligne dans ItemTableView, la fonction didSelectItem est appelé dans le instance de ContainerView qui a présenté le ItemTableView. Le ItemTableView n'est pas rejeté - l'utilisateur peut continuer à sélectionner des éléments.
  5. ContainerView soumet une requête au serveur
  6. En fonction de la réponse, le ContainerView peut présenter un UIAlertView.
  7. Le alertView est correctement affiché en utilisant le code mentionné ci-dessus en plus de l'affichage qui est le plus haut dans la hiérarchie.
0

« Lorsque l'utilisateur sélectionne un élément, il déclenche et l'action sur le délégué »

définir un point d'arrêt au début de la méthode déléguée qui est déclenché par la sélection d'un élément. vérifier si cette méthode déléguée est appelée ou non?

et testez-le également. (ACTION :UIAlertAction!)in