[Résolu] Erreur : Attempt to present UIAlertController which is already presenting !!!
Bonjour tous,
après avoir parcouru pour une seconde fois plein de pages sur le web sur le sujet, je reviens au bar, car je n'ai pas trouvé la solution. J'ai fait tous les tests possibles, et je ne comprend vraiment pas ce truc.
Dans un autre de mes viewControllers, j'ai eu le même problème, que j'ai résolu en mettant mon code d'alerte dans le viewDidAppear. Mais c'était logique, car j'avais besoin de cette alerte à l'entrée sur la vue correspondante.
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
let ecartLignesPixels = abs((poigneeTopRightX + poigneeBottomRightX)/2 - poigneeTopCenterX)
let ecartLignesMms = round((CGFloat(ecartLignesPixels) * mesureMm / mesure)*1000) / 1000
if ecartLignesPixels == ecartLignesMms {
let alertMesures: UIAlertController = UIAlertController(title: "Mesures", message: "Attention,\ntous les calculs seront faux.\nRetournez sur l'écran d'accueil,\ncliquez sur la photo 3, puis,\nentrez les mesures en pixel et mm.", preferredStyle: .Alert)
let fermerMesures = UIAlertAction(title: "Fermer", style: .Cancel) { action -> Void in
pagesNavigationController.popToRootViewControllerAnimated(true)
}
alertMesures.addAction(fermerMesures)
self.presentViewController(alertMesures, animated: true, completion: nil)
}
}
Par contre, là j'ai besoin d'une alerte, après avoir cliqué dans une dans une view déjà présentée en popoverController. Donc au sein de la méthode suivante
func bouches2eNormalTap(recognizer: UITapGestureRecognizer) {
let tap = recognizer as UITapGestureRecognizer
if tap.state == .Ended {
.....
Je ne met que le code utile.
// Alert du choix si on ajoute
let alertImagePicto2: UIAlertController = UIAlertController(title: "Second choix", message: "àŠtes-vous certain de vouloir ajouter un second choix ?", preferredStyle: .Alert)
// Ajout - Donc insertion imagepicto2
let ajoutImagePicto2 = UIAlertAction(title: "Ajouter", style: .Destructive) { action -> Void in
self.imagePicto.frame = CGRectMake(14,self.boutonPositionY - 95, 113, 75)
self.imagePicto2 = UIImageView(frame: CGRectMake(143,self.boutonPositionY - 95, 113, 75))
self.imagePicto2.backgroundColor = FondsColor
self.imagePicto2.layer.shadowColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.40).CGColor
self.imagePicto2.layer.shadowOffset = CGSize(width: 2, height: 2)
self.imagePicto2.layer.shadowOpacity = 0.5
self.imagePicto2.layer.shadowRadius = 10
self.imagePicto2.layer.cornerRadius = 5
self.e2L5Position2String = self.labelsResultat[0]
self.bouches2eViewController.label2eNormal.textColor = self.ChoixColor
}
alertImagePicto2.addAction(ajoutImagePicto2)
// Pas d'ajout - Donc modification imagepicto (1)
let noAjoutImagePicto2 = UIAlertAction(title: "Annuler", style: .Cancel) { action -> Void in
self.e2L5PositionString = self.labelsResultat[0]
self.bouches2eViewController.label2eNormal.textColor = self.ChoixColor
self.bouches2eViewController.label2eProalveolie.textColor = self.BaseColor
self.bouches2eViewController.label2eRetroalveolie.textColor = self.BaseColor
self.bouches2eViewController.label2eRetrusion.textColor = self.BaseColor
self.bouches2eViewController.label2eProtrusion.textColor = self.BaseColor
self.dismissViewControllerAnimated(true, completion: nil)
self.imagePicto.image = UIImage(named: self.imagesResultat[0])
}
alertImagePicto2.addAction(noAjoutImagePicto2)
self.presentViewController(alertImagePicto2, animated: true, completion: nil)
Et voici l'erreur :
Warning: Attempt to present <UIAlertController: 0x7f89d3153030> on <GuideEsthetique.Etape2L5ViewController: 0x7f89d188b800> which is already presenting (null)
Si quelqu'un a une idée lumineuse, parce que là , je sèche.
Merci d'avance.
Réponses
ça devrait te permettre de voir dans quelles circonstances exactes il est appelé.
Merci Ceroce, mais je sais exactement quand...
Bon, j'en ai mis un pour voir.
Et ça ne m'apprend rien, si ce n'est que ça me met la puce à l'oreille sur ce que je savais déjà , et expliqué plus haut.
Soit, je suis déjà sur un gesture recognizer... dans un popover...
Deux fois de suite. Pour moi c'est impossible.
C'est dans un UITapGestureRecognizer
Parce que ce qui arrive souvent c'est qu'on ne comprenne pas qu'une méthode soit appelée deux fois de suite jusqu'à qu'on se rende compte qu'elle est appelée sur deux instances différentes, par exemple.
Heu, ben non j'ai un gestore et un alert - tout est différent et pas nommé pareil
Ah, ben j'ai plusieurs recognizer dans mon popover (j'ai des pictos sur lesquels je clique)
Mais pour l'instant je n'ai mis qu'une alerte sur le premier picto pour tester clean et facile.
Donc je n'ai qu'une instance...
Regarde si c'est bien l'instance de UIAlertController que tu attends (il a le bon message ?).
Je sais pas faire
en survol je crois les voir mais tout semble unique
Essaie de désactiver ton gesture recognizer.
Ecoute, je pense avoir une piste, mais ne sait pas comment la suivre.
Il se trouve que comme je suis dans un popover, et que je puisse cliqué sur chacun des 5 pictos inclus dedans (chacun son gesture), il est évident que j'ai un :
pour fermer le popover après le click.
D'ailleurs tous les autres clicks fonctionnent.
Mais sur le premier picto (et ce sera sur tous), j'ai mis une alerte, et donc j'ai aussi un :
mais ce coup-ci, c'est pour fermer l'alert.
Donc, c'est sur, y'a conflit...
C'est chaud, hein...
Si la cause est bien le conflit que tu suspectes, pourquoi ne pas afficher ton alerte après la fermeture du popover via une notification avec un délai ?
- soit on ferme le popover et on applique l'action
- soit on affiche une alerte.
En fait, ce n'est pas si compliqué: là , tu fermes le popover dès qu'on tap... il ne faut pas. Il faut juste que tu évalues la condition d'affichage de l'alerte avant.
Possible mais je préfère poser une question évidente plutôt qu'interpréter les dires des autres.
L'expérience montre que les réponses sont souvent différentes.
Ben tout ce que venez de dire est valable.
J'ai donc mis tout le code dans un
Et le code pour fermer le popover dans
Du coup, plus d'erreur, mais plus d'alerte - grrrr
UITapGestureRecognizer
seulement le ended pas de began ni changed
pas de chance
Je crois que je vais essayer le délai dont parle Eric P.
En espérant que ça fonctionne
Bon, j'ai essayé avec un timer - C'est pareil.
J'ai essayé en supprimant tous les dismiss. C'est pareil.
J'ai essayé en ne gardant que mon action .Cancel. C'est pareil.
Je met donc un code simplifié de base pour les docteur barmen
ça, ça marche nickel :
ça, ça marche pas (même code) :
C'est un problème de fond qui m'échappe.
Y'a plus de dismiss, plus de conflit, etc... Et toujours cette erreur.
Génial... Qu'est-ce-qu'on s'éclate lorsque l'on manque de connaissance. C'est ça l'aventure.
Si tu ajoutes un dans
un println("Test"), il ne l'affiche bien qu'une fois ?
PS : bien maà®triser les points d'arrêt, etc. (si tu n'es pas ok là -dessus), c'est un investissement qui te fera gagner 1000 heures.
oui oui oui - merci quand même
C'est quand même dingue que sur le web (je n'arrête pas de changer mes requêtes) on ne trouve strictement rien sur les problèmes concernant l'apparition d'une alerte suite à un click dans un popOver.
Je reconnais que c'est chaud de faire apparaà®tre une fenêtre popUp à partir d'une autre fenêtre popUp.
Mais je développe pour le web (sites web - php, jQuery, etc...), et là on peut imbriquer n'importe quoi dans n'importe quoi, en respectant les règles, évidemment. Il suffit de bien nommer ses variables. Là , chez Apple, y'a quand même un problème de concept de chez concept, non ?
Ou bien, mon histoire est débile, à savoir prévenir l'utilisateur, de quelque chose (...), suite à un click dans un popOver.
Je crois que je vais me faire une view perso, mais c'est super relou quand même. Booouuuuhhh...
Purée, à force de faire plein de trucs débiles, je crois avoir trouvé.
C'est vraiment débile.
J'avais toutes les infos dans les réponses à mon post, mais il fallait juste remettre de l'ordre dans tout ça, et aussi dans mon cerveau.
Il fallait juste fermer le popOver avant la détection du state .Ended. C'est vraiment con tout ça.
Donc, pour ceux qui auraient besoin de ce genre de trucs qui semble très rarement utilisé, voici le code :
Encore merci pour l'aide des barmen, sans laquelle je n'aurai jamais trouvé.
Je viens de créer un nouveau projet et de copier/coller ton code ci-dessus, en connectant la fonction bouches2eNormalTap à un UITapRecognizer sur la View principale, et tous marche bien.
Bien sûr il y a quelques autres problèmes avec ton code, niveau transmission de self dans un closure, niveau fermeture d'une vue juste après son ouverture, mais je les laisse pour le moment.
Ah, salut Joanna Carter.
Je savais que t'allais venir... Cool...
Excuse moi, si je te répond tardivement.
Bon, tu as du voir, que j'ai trouvé la solution...
avant toute détection.
C'est Eric P. qui as mis le doigt dessus, en fait. Mais j'ai mis du temps à comprendre. Et Ceroce, aussi m'a bien aidé.
Sans quoi, pour te répondre plus précisément :
Je sais bien que les self sont indispensables dans les closures. De toute façon, c'est Xcode qui me le dit, et non pas ma culture, quoique aujourd'hui, je le sais, grave (à force... d;-)).
En tout cas, ta remarque me donne envie de faire comme toi. De créer un projet vide et nouveau et d'intégrer ce code (le code simple ci-dessus, on est bien d'accord), et de voir le même résultat que toi. Bien que je sois sceptique, mais j'ai plutôt confiance en toi qu'en mes supputations personnelles... ::)
Et je suis tellement la tête dans le guidon (commDab'), que je ferais cela bien plus tard si j'y repense. Je suis désolé pour toi, enfin surtout pour moi, et je sais que tu t'en fous un peu, et que t'as bien raison... ::)
En gros, merci au bar. Je met Résolu, mais je reste quand même attentif à toutes remarques...Qui m'intéressent énormément.
Au fait, j'oubliais, je met le code complet pour ceux que ça intéresse.
Même si cela n'est pas super passionnant.
Enfin, y'a les commentaires qui sont presque, à mon goût, plus intéressants que le code.
Je précise que bouches2eViewController est d'après un XIB avec son vieswcontroller qui contient les outlets (genre label2eNormal...).
Et je me rend compte que les self.dismissViewControllerAnimated(true, completion: nil) ne servent à rien, en fait. ça, ça m'épate grave.
1- le code sans alerte, qui fonctionne parfaitement :
2- Le code avec alerte, qui fonctionne maintenant, heu, parfaitement (enfin, il semble, pour l'instant) :
À la votre
Quand on a passé une journée entière sur un problème, on a du mal à en voir l'issue. C'est l'une des limites du travail solitaire: on n'a pas un collègue pour jeter un oe“il neuf (et moins fatigué).
Je n'avais pas la solution en lisant ton code, mais je t'ai incité à changer de méthode de débogage, et c'est ça qui a décoincé la situation. Pas la méthode de débogage, mais le fait que tu prennes un peu de recul. La solution ne se trouvait pas ton code, mais dans ta tête.
mais plutôt le faire de la manière suivante:
En tous cas, il me semble que dans le passé j'ai eu des problèmes avec ce genre d'enchaà®nements.