Problème d’UINavigation d’iPhone – l’animation poussée nestede peut entraîner une barre de navigation corrompue

Je continue à recevoir les erreurs suivantes:

2011-04-02 14:55:23.350 AppName[42430:207] nested push animation can result in corrupted navigation bar 2011-04-02 14:55:23.352 AppName[42430:207] nested push animation can result in corrupted navigation bar 2011-04-02 14:55:23.729 AppName[42430:207] Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted. 2011-04-02 14:55:23.729 AppName[42430:207] Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted. 

Voici ce que je fais. Depuis un contrôleur de vue, j’appelle ce qui suit lorsqu’un bouton est enfoncé:

 EventsViewController *viewController = [[EventsViewController alloc] init]; UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController]; navController.navigationBar.tintColor = [UIColor blackColor]; [self presentModalViewController:navController animated:YES]; [viewController release]; [navController release]; 

Ensuite, si un certain bouton est enfoncé dans EventsController, j’appelle:

 SingleEventViewController *viewController = [[SingleEventViewController alloc] initWithEvent:[currentEvents objectAtIndex:indexPath.row]]; [self.navigationController pushViewController:viewController animated:YES]; [viewController release]; 

Ensuite, si un bouton est poussé dans SingleEventViewController, j’appelle:

 EventMapView* viewController = [[EventMapView alloc] initWithCoordinates]; [[self navigationController] pushViewController:viewController animated:YES]; [viewController release]; 

Alors oui, il est évident qu’il y a des animations push nestedes, mais n’est-ce pas la bonne façon de s’y prendre? J’ai vérifié le code DrillDownSave d’Apple et cela semble être la façon dont ils le font. Est-ce important que j’utilise les méthodes init au lieu des méthodes viewDidLoad?

L’appel de pushViewController avant viewDidAppear est dangereux.

EN CAS DE DÉCLENCHEMENT ACCIDENTEL DE LA MÊME SEGUE DEUX FOIS Une fois dans le code, et une fois dans le générateur d’interface, mais les deux en même temps …

Je faisais la même erreur que vous. Seul mon problème était que je tirais accidentellement la même fois, deux fois. Une fois depuis le générateur d’interface et une fois depuis mon code.

J’ai un UITableView. Lorsqu’une cellule est sélectionnée, un segue dans le générateur d’interface se déclenche. Voici mon problème: la segue a été configurée pour être lancée directement en cliquant sur CELL ITSELf, dans le générateur d’interface, puis dans mon code, j’avais sous didSelectRowAtIndexPath, le code qui déclencherait ce même segue … comme ça …

 [self performSegueWithIdentifier:@"MySegue" sender:tableView]; 

Cela signifie que lorsque didSelectRowAtIndexPath est appelé car une ligne a été sélectionnée, il déclenche le lien avec la ligne de code ci-dessus. Ensuite, le générateur d’interface déclenche également le segue, car il est connecté directement à l’object cellule dans le générateur d’interface. Pour empêcher le générateur d’interface de déclencher directement le segue. Vous devez connecter le segue à partir du haut du contrôleur de vue, pas nested à l’intérieur de la cellule elle-même.

Donc, si vous rencontrez ce problème pour la même raison que moi, c’est-à-dire que vous appelez la même fois deux fois, vous pouvez résoudre ce problème en dissociant la connexion de CELL DIRECTLY, avec votre segue, et en établissant la connexion haut de la hiérarchie des tables dans IB, plutôt que nestedes dans la cellule. Connectez le segue de votre View Controller lui-même, au segue. Si vous avez fait ceci correctement, lorsque vous sélectionnez le segue, il devrait mettre en évidence la vue ENTIRE dont il provient, pas seulement la cellule.

Désormais, la documentation Apple indique sous performSegueWithIdentifier: expéditeur: référence:

Les applications n’ont normalement pas besoin de déclencher directement des segues. Au lieu de cela, vous configurez un object dans Interface Builder associé au contrôleur de vue, tel qu’un contrôle incorporé dans sa hiérarchie de vues, pour déclencher le segue. Toutefois, vous pouvez appeler cette méthode pour déclencher un segment par programmation, peut-être en réponse à une action qui ne peut pas être spécifiée dans le fichier de ressources du storyboard. Par exemple, vous pouvez l’appeler à partir d’un gestionnaire d’actions personnalisé utilisé pour traiter les événements de shake ou d’accéléromètre.

Dans mon cas, j’ai un bouton de recherche pour mon UITableView, et il fallait déterminer si la segue est appelée lorsque la table de résultats de recherche est présente ou si la vue de table normale est présente. Il fallait donc que je déclenche directement le segue.

Supprimez donc le contrôle incorporé du générateur d’interface et collez-le simplement sur le contrôleur de vue, puis déclenchez le segue dans votre code!

Maintenant, plus de doubles segues! Et plus d’erreurs.

J’espère que ça aide, il m’a fallu quelques heures pour m’attaquer à celui-ci.

J’avais le même message d’erreur / message d’erreur que vous veniez de le faire, cherchait une solution et finissais par ce sujet, cependant, pour moi, la solution ne comportait qu’une seule animation: OUI mettre l’animation: OUI seulement pour la poussée finale), j’espère que cela vous aidera

à votre santé.

J’ai compris Apparemment, si vous appelez -pushViewController en dehors de la méthode -didSelectRowAtIndexPath d’un object UITableViewDelegate, cela ne fonctionne pas. Déplacer l’appel dans cette fonction a fonctionné. Bizarre.

Je suis tombé sur ce même problème qui résultait d’un bouton dans une plume étant connecté à deux actions différentes. Il a essayé de charger les deux contrôleurs de vue, corrompant ainsi la stack.

Qu’est-ce que vous voulez dire quand vous dites que vous utilisez des méthodes init au lieu des méthodes viewDidLoad?

Si vous poussez un nouveau contrôleur de vue avant que l’ancienne action n’ait une chance de se déclencher, vous obtiendrez ce type d’erreur. Donc, mettre du code dans init et faire des choses prématurément peut certainement vous amener à signaler l’erreur.

Au moment où init est exécuté sur un contrôleur de vue, la vue n’a pas encore été chargée!

J’ai eu ce problème, et je suis nouveau sur toute la scène de développement iOS. Mais après avoir regardé mon inspecteur des connexions (avec le propriétaire du fichier) dans le générateur d’interface, j’ai vu que j’avais copié un bouton, la méthode des boutons précédents ainsi que la nouvelle méthode que j’avais créée. Je suppose que c’est de là que venait l’aspect nested de mon problème, car il exécutait 2 méthodes différentes, toutes deux poussant une vue sur le contrôleur de navigation. Je sais que cela a déjà été répondu mais je pensais que je mettrais ça juste au cas où quelqu’un d’autre aurait une erreur stupide comme la mienne.

Cela a déjà été répondu, mais je pensais que cela pourrait aider les autres car j’ai la même erreur, mais sans utiliser les vues de table. J’ai finalement compris le problème.

J’avais un bouton existant dont IBAction invoquait un pushViewController. J’avais créé un nouveau bouton en copiant le bouton existant. Le nouveau bouton comportait également une action qui invoquait pushViewController. Lorsque le nouveau bouton a été tapé (retouche à l’intérieur) et que le contrôleur de vue a été poussé, j’ai eu cette erreur. J’ai supprimé le nouveau bouton, l’ai créé à partir de zéro, l’ai lié aux sockets et actions existantes et l’erreur a disparu.

Ran dans le même problème. Dans mon cas, je manquais une pause dans la déclaration de changement de façon à ce que deux segues soient licenciées en même temps. Solution facile pour moi.

Mon problème était lié au fait que le clavier était actif.

Cela a été causé pour moi en poussant un ViewController de la méthode délégué textField:

 -(void)textFieldDidBeginEditing:(UITextField *)textField{ FilterLocationViewController *destViewController = (FilterLocationViewController *)[self.storyboard instantiateViewControllerWithIdentifier:@"FilterLocationViewController"]; [self.navigationController pushViewController:destViewController animated:YES]; } 

En changeant le code à ceci:

 -(void)textFieldDidBeginEditing:(UITextField *)textField{ [_textFieldLocation resignFirstResponder]; //adding this line FilterLocationViewController *destViewController = (FilterLocationViewController *)[self.storyboard instantiateViewControllerWithIdentifier:@"FilterLocationViewController"]; [self.navigationController pushViewController:destViewController animated:YES]; } 

(en ajoutant la ligne [textField resignFirstResponder]; ) le problème a disparu.

La leçon est que vous ne devez pas modifier la stack de navigationController si le clavier est éteint.

Récemment, j’ai rencontré le même problème. La raison était: -J’essayais de faire apparaître le contrôleur deux fois par erreur. vous pouvez vérifier cette panne en définissant des points d’arrêt sur les contrôleurs View et Pop View

1) Peut-être pourriez-vous essayer de transmettre les variables nécessaires en tant que propriétés avant de UIViewController plutôt que d’utiliser les méthodes init avec des parameters. Vous aurez probablement besoin de ces parameters au-delà de votre méthode init.

En outre, dans votre méthode initWithCoordinates: vous manquez les parameters. Peut-être que vos méthodes d’initialisation personnalisées font partie du problème.

2) Tout simplement parce que vous avez mentionné viewDidLoad – cette méthode est destinée à l’initialisation après le chargement d’une vue. Si vous créez le code UIViewController, comme vous loadView faire, vous devez utiliser loadView pour configurer vos sous-vues.

Cela se passait pour moi à cause de mes UIControlEvents

  [button addTarget:self action:@selector(callSecondView) forControlEvents:UIControlEventAllTouchEvents]; 

J’ai dû modifier le UIControlEventAllTouchEvents à UIControlEventTouchUpInside ou si vous voulez que votre bouton fonctionne si vous aviez le problème en raison d’un appel UIButton.

Ma solution était

[self performSelector: @selector (moveTo) avecObject: nil afterDelay: 0.5];

Je ne sais pas pour les autres. Je pense que la plupart des personnes utilisant StoryBoard sont confrontées à un tel problème. J’utilise XIB.

Dans mon cas, le problème était, quand je passais à une autre vue en utilisant push, j’utilisais aussi

  [self.navigationController popViewControllerAnimated:YES]; 

dans le ViewWillDisappear de la vue actuelle en même temps. Il suffit de le retirer et cela fonctionne bien.

J’utilisais POP, à cause de l’exigence et du Flow. La hiérarchie était 1 -> 2 -> 3

J’étais sur la vue 2 et je voulais passer à la vue 3. Dans ce cas, j’ai rencontré cette erreur.

Dans mon cas, j’étais à la fois en train de mettre le point sur le storyboard et par programmation. Espérons que cela aidera quelqu’un

J’ai eu ce message d’erreur aussi, et les transitions de la barre de navigation et du contrôleur de navigation étaient bizarres. Ma configuration était un groupe de contrôleurs de navigation intégrés dans un contrôleur de barre de tabulation. Le problème était que je n’appelais pas super.viewDidLoad() dans l’implémentation de viewDidLoad dans la barre de viewDidLoad .

L’appel de super est quelque chose que les docs indiquent clairement que vous devriez faire lorsque vous remplacez viewDidLoad, et j’ai appris cela à la dure.

Peut-être que cela peut aussi aider quelqu’un d’autre!

Je sais que cela a été répondu, mais cela pourrait aider les autres.

J’ai eu le même problème, mais cela était dû au fait que j’utilisais un mauvais événement pour un bouton d’information. J’utilisais “UIControlEventAllTouchEvents” et cela générait deux poussées de la même vue dans le contrôleur de navigation. L’événement correct était “UIControlEventTouchUpInside”. Je suis nouveau sur iOS.

Cela résout le problème: https://github.com/nexuspod/SafeTransition

Si vous poussez (ou pop) un contrôleur de vue avec animation (animé: OUI), il ne se termine pas tout de suite et de mauvaises choses se produisent si vous faites un autre push ou pop avant la fin de l’animation.

Pour reproduire ce bogue, essayez de pousser ou d’écraser deux contrôleurs de vue en même temps. Exemple:

 - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; UIViewController *vc = [[UIViewController alloc] init]; [self.navigationController pushViewController:vc animated:YES]; } 

Vous recevrez cette erreur:

2014-07-03 11: 54: 25.051 Demo [2840: 60b] L’animation push nestede peut entraîner une barre de navigation corrompue . L’arborescence de sous-vues de la barre de navigation peut être corrompue.

Ajoutez simplement les fichiers de code dans votre projet et faites de votre contrôleur de navigation une sous-classe de APBaseNavigationController, et vous serez prêt à le faire.

Juste pour compléter la liste, voici une autre raison qui peut provoquer “l’animation push nestede peut entraîner une barre de navigation corrompue”:

J’ai configuré plusieurs NavigationController dans un TabBarController et défini l’index selectedIndex dans les propriétés d’identification du storyboard. Après avoir déplacé l’onglet actif sur l’erreur de code a disparu.