Je viens de commencer à utiliser Xcode 4.5 et j'ai eu cette erreur dans la console:
Avertissement: essayez de présenter <finishViewController: 0x1e56e0a0> sur <ViewController: 0x1ec3e000> dont la vue n'est pas dans la hiérarchie des fenêtres!
La vue est toujours présentée et tout dans l'application fonctionne bien. Est-ce quelque chose de nouveau dans iOS 6?
Voici le code que j'utilise pour changer entre les vues:
UIStoryboard *storyboard = self.storyboard;
finishViewController *finished =
[storyboard instantiateViewControllerWithIdentifier:@"finishViewController"];
[self presentViewController:finished animated:NO completion:NULL];
presentViewController:animated:completion
un contrôleur de navigation. Faites-vous cela dans le délégué de l'application?Réponses:
D'où appelez-vous cette méthode? J'ai eu un problème où j'essayais de présenter un contrôleur de vue modale dans la
viewDidLoad
méthode. La solution pour moi a été de déplacer cet appel vers laviewDidAppear:
méthode.Ma présomption est que la vue du contrôleur de vue n'est pas dans la hiérarchie des vues de la fenêtre au moment où elle a été chargée (lorsque le
viewDidLoad
message est envoyé), mais elle est dans la hiérarchie des fenêtres après sa présentation (lorsque leviewDidAppear:
message est envoyé) .Mise en garde
Si vous appelez
presentViewController:animated:completion:
dans le,viewDidAppear:
vous pouvez rencontrer un problème où le contrôleur de vue modale est toujours présenté chaque fois que la vue du contrôleur de vue apparaît (ce qui a du sens!) Et ainsi le contrôleur de vue modale présenté ne disparaîtra jamais. .Peut-être que ce n'est pas le meilleur endroit pour présenter le contrôleur de vue modale, ou peut-être qu'un état supplémentaire doit être conservé qui permet au contrôleur de vue de présentation de décider s'il doit ou non présenter immédiatement le contrôleur de vue modale.
la source
Une autre cause potentielle:
J'ai eu ce problème lorsque je présentais accidentellement deux fois le même contrôleur de vue. (Une fois avec
performSegueWithIdentifer:sender:
qui a été appelé lorsque le bouton a été enfoncé, et une deuxième fois avec une séquence connectée directement au bouton).Effectivement, deux séquences tiraient en même temps, et j'ai eu l'erreur:
Attempt to present X on Y whose view is not in the window hierarchy!
la source
present(viewController, animated: true, completion: nil)
dans une boucle.viewWillLayoutSubviews
etviewDidLayoutSubviews
(iOS 5.0+) peuvent être utilisés à cette fin. Ils sont appelés plus tôt que viewDidAppear.la source
Pour afficher une sous-vue à la vue principale, veuillez utiliser le code suivant
Pour rejeter toute sous-vue de la vue principale, veuillez utiliser le code suivant
la source
J'ai également rencontré ce problème lorsque j'ai essayé de présenter un fichier
UIViewController
inviewDidLoad
. La réponse de James Bedford a fonctionné, mais mon application a affiché l'arrière-plan en premier pendant 1 ou 2 secondes.Après quelques recherches, j'ai trouvé un moyen de résoudre ce problème en utilisant le
addChildViewController
.la source
Probablement, comme moi, vous avez une mauvaise racine
viewController
Je veux afficher un
ViewController
dans unnon-UIViewController
contexte,Je ne peux donc pas utiliser un tel code:
Donc, je reçois un UIViewController:
Pour une raison quelconque (bogue logique), le
rootViewController
est autre chose que prévu (un normalUIViewController
). Ensuite, je corrige le bogue, en le remplaçantrootViewController
par unUINavigationController
, et le problème a disparu.la source
TL; DR Vous ne pouvez avoir qu'un seul rootViewController et son dernier présenté. N'essayez donc pas de faire en sorte qu'un viewcontroller présente un autre viewcontroller alors qu'il est déjà présenté, qui n'a pas été rejeté.
Après avoir fait mes propres tests, je suis arrivé à une conclusion.
Si vous avez un rootViewController que vous souhaitez tout présenter, vous pouvez rencontrer ce problème.
Voici mon code rootController (ouvert est mon raccourci pour présenter un viewcontroller depuis la racine).
Si j'appelle ouvert deux fois de suite (quel que soit le temps écoulé), cela fonctionnera très bien lors de la première ouverture, mais PAS lors de la deuxième ouverture. La deuxième tentative d'ouverture entraînera l'erreur ci-dessus.
Cependant, si je ferme la dernière vue présentée et que j'appelle open, cela fonctionne très bien lorsque j'appelle à nouveau open (sur un autre viewcontroller).
Ce que j'ai conclu, c'est que le rootViewController de seulement le MOST-RECENT-CALL est sur la hiérarchie des vues (même si vous ne l'avez pas supprimé ou supprimé une vue). J'ai essayé de jouer avec tous les appels du chargeur (viewDidLoad, viewDidAppear et faire des appels de répartition retardés) et j'ai trouvé que la seule façon de le faire fonctionner est d'appeler SEULEMENT le plus haut contrôleur de vue.
la source
wait
wait
decide
push screen to front
et c'est IMPOSSIBLE est IOS ????Mon problème était que j'effectuais
UIApplicationDelegate
ladidFinishLaunchingWithOptions
méthode de transition avant d'appelermakeKeyAndVisible()
à la fenêtre.la source
Dans ma situation, je n'ai pas pu mettre la mienne dans une dérogation de classe. Alors, voici ce que j'ai obtenu:
la source
J'ai eu le même problème. J'ai dû intégrer un contrôleur de navigation et présenter le contrôleur à travers. Voici l'exemple de code.
la source
Si vous avez un objet AVPlayer avec une vidéo lue, vous devez d'abord mettre la vidéo en pause.
la source
J'ai eu le même problème. Le problème était que le performSegueWithIdentifier a été déclenché par une notification, dès que j'ai mis la notification sur le thread principal, le message d'avertissement avait disparu.
la source
Cela fonctionne bien, essayez ceci. Lien
la source
Au cas où cela aiderait quelqu'un, mon problème était extrêmement stupide. Tout à fait ma faute bien sûr. Une notification déclenchait une méthode qui appelait le modal. Mais je ne supprimais pas la notification correctement, donc à un moment donné, j'aurais plus d'une notification, donc le modal serait appelé plusieurs fois. Bien sûr, après avoir appelé le modal une fois, le viewcontroller qui l'appelle n'est plus dans la hiérarchie des vues, c'est pourquoi nous voyons ce problème. Ma situation a également causé un tas d'autres problèmes, comme vous vous en doutez.
Donc, pour résumer, quoi que vous fassiez, assurez-vous que le modal n'est pas appelé plus d'une fois .
la source
Je me suis retrouvé avec un tel code qui fonctionne finalement pour moi (Swift), étant donné que vous voulez en afficher
viewController
pratiquement n'importe où. Ce code se bloquera évidemment lorsqu'il n'y a pas de rootViewController disponible, c'est la fin ouverte. Il n'inclut pas non plus le passage habituellement requis au thread d'interface utilisateur à l'aidela source
Ce genre d'avertissement peut signifier que vous essayez de présenter de nouvelles à
View Controller
traversNavigation Controller
tout ceNavigation Controller
présente actuellement une autreView Controller
. Pour le réparer Vous devez rejeter actuellement présentéView Controller
au début et à la fin présenter le nouveau. Une autre cause de l'avertissement peut être d'essayer de présenterView Controller
sur un thread autre quemain
.la source
J'ai eu un problème similaire sur Swift 4.2 mais ma vue n'a pas été présentée à partir du cycle de vue. J'ai trouvé que j'avais plusieurs séquences à présenter en même temps. J'ai donc utilisé dispatchAsyncAfter.
la source
Je l'ai corrigé en déplaçant la
start()
fonction à l'intérieur dudismiss
bloc de complétion:Start contient deux appels à l'
self.present()
un pour un UINavigationController et à un autre pour aUIImagePickerController
.Cela m'a arrangé.
la source
Vous pouvez également obtenir cet avertissement lorsque vous effectuez une séquence à partir d'un contrôleur de vue incorporé dans un conteneur. La bonne solution consiste à utiliser segue depuis le parent du conteneur, et non depuis le contrôleur de vue du conteneur.
la source
Vous devez écrire sous la ligne.
au lieu de
dans UIViewController
la source
Avec Swift 3 ...
Une autre cause possible à cela, qui m'est arrivée, était d'avoir une transition d'une tableViewCell à un autre ViewController sur le Storyboard. J'ai également utilisé
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {}
lorsque la cellule a été cliquée.J'ai résolu ce problème en effectuant une transition de ViewController à ViewController.
la source
J'ai eu ce problème et la cause principale était de s'abonner plusieurs fois à un gestionnaire de clic de bouton (TouchUpInside).
Il s'abonnait dans ViewWillAppear, qui était appelé plusieurs fois depuis que nous avions ajouté la navigation pour accéder à un autre contrôleur, puis y revenir.
la source
Il m'est arrivé que la séquence dans le storyboard était une sorte de rupture . La suppression de la séquence (et la création de la même séquence exacte à nouveau) a résolu le problème.
la source
Avec votre fenêtre principale, il y aura probablement toujours des moments avec des transitions incompatibles avec la présentation d'une alerte. Afin de permettre la présentation d'alertes à tout moment dans le cycle de vie de votre application, vous devez disposer d'une fenêtre distincte pour effectuer le travail.
Utilisation de base qui, par conception, réussira toujours:
la source
Malheureusement, la solution acceptée n'a pas fonctionné pour mon cas. J'essayais de naviguer vers un nouveau contrôleur de vue juste après me détendre à partir d'un autre contrôleur de vue.
J'ai trouvé une solution en utilisant un indicateur pour indiquer quelle séquence de déroulement a été appelée.
Ensuite, présentez le VC recherché avec
present(_ viewControllerToPresent: UIViewController)
Fondamentalement, le code ci-dessus me permettra d'attraper le déroulement de la connexion / SignUp VC et d'accéder au tableau de bord, ou d'attraper l'action de déroulement du mot de passe oublié VC et d'accéder à la page de connexion.
la source
J'ai corrigé cette erreur en stockant le plus haut viewcontroller dans une constante qui se trouve dans pendant le cycle sur rootViewController:
la source
J'ai trouvé que ce bug est arrivé après la mise à jour de Xcode, je crois pour Swift 5 . Le problème se produisait lorsque j'ai lancé par programmation un enchaînement directement après avoir déroulé un contrôleur de vue.
La solution est arrivée en corrigeant un bogue connexe, à savoir que l'utilisateur était désormais en mesure de dérouler les séquences en faisant glisser la page vers le bas. Cela a brisé la logique de mon programme.
Il a été corrigé en changeant le mode de présentation sur tous les contrôleurs de vue d' Automatique à Plein écran .
Vous pouvez le faire dans le panneau d'attributs du générateur d'interface. Ou consultez cette réponse pour savoir comment procéder par programme.
la source
Je viens d'avoir ce problème aussi, mais cela n'a rien à voir avec le timing. J'utilisais un singleton pour gérer les scènes, et je l'ai défini comme le présentateur. En d'autres termes, "Self" n'était lié à rien. Je viens de faire de sa "scène" intérieure le nouveau présentateur et le tour est joué, ça a marché. (Voila perd son contact après avoir appris sa signification, heh).
Donc oui, il ne s'agit pas de "trouver par magie la bonne voie", il s'agit de comprendre où se trouve votre code et ce qu'il fait. Je suis heureux qu'Apple ait donné un message d'avertissement aussi simple en anglais, même avec émotion. Félicitations au développeur de pommes qui a fait ça !!
la source
Si d'autres solutions ne semblent pas bonnes pour une raison quelconque, vous pouvez toujours utiliser cette bonne vieille
workaround
présentation avec le retard de 0, comme ceci:Bien que je n'aie vu aucune garantie documentée que votre VC serait dans la hiérarchie des vues sur le moment où le bloc de répartition est planifié pour l'exécution, j'ai observé que cela fonctionnerait très bien.
L'utilisation d'un retard de 0,2 sec, par exemple, est également une option. Et la meilleure chose - de cette façon, vous n'avez pas besoin de jouer avec la variable booléenne dans
viewDidAppear:
la source
Cela fonctionne pour présenter n'importe quel contrôleur de vue, si vous avez un contrôleur de navigation disponible. self.navigationController? .present (MyViewController, animé: vrai, achèvement: nul) De plus, je peux également présenter des alertes et un contrôleur de messagerie.
la source