36 votes

UIViewControllerHierarchyInconsistency lors de la présentation d'un contrôleur de vue modal

J'essaie de présenter un contrôleur de vue modal avec le code suivant

MapViewController *mapView = [[MapViewController alloc] initWithNibName:@"MapViewController" bundle:nil];
    mapView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
    [self.navigationController presentModalViewController:mapView animated:YES];
    [mapView release];

Je continue à obtenir l'erreur suivante

'UIViewControllerHierarchyInconsistency', reason: 'A view can only be associated with at most one view controller at a time! View <UIView: 0x1ed815a0; frame = (0 20; 320 460); autoresize = W+H; layer = <CALayer: 0x1ed81600>> is associated with <UIViewController: 0x1ed835a0>. Clear this association before associating this view with <MapViewController: 0x1dd947c0>.'

Il s'agit d'un vieux projet que je n'ai pas touché depuis des mois, je me demande ce qui peut provoquer une telle erreur.

149voto

Lukasz Points 6474

Cela m'est déjà arrivé deux fois dans la dernière version de Xcode. Dans les deux cas, j'ai dû modifier le fichier XIB de l'UIViewController (dans votre cas, il s'agit de MapViewController.xib :

AVANT :

enter image description here

  1. Déplacer la vue principale hors de Le contrôleur de vue enfants :
  2. Retirer View Controller du XIB (ce n'est pas nécessaire puisque le Propriétaire du dossier devrait déjà faire partie de sa classe) :

APRÈS :

enter image description here

8voto

user1681572 Points 946

J'ai rencontré ce problème en exécutant l'application audio d'Apple MixerHost sur le simulateur iOS 6.

L'équivalent de la correction ci-dessus, à savoir éditer le fichier MixerHostViewController.xib fourni en faisant glisser l'objet View au niveau supérieur, et en supprimant le ViewController désormais vide qui le contenait, a parfaitement fonctionné (mais pas avant que j'aie passé des heures à trouver quel était le problème sous-jacent, je me sens donc refroidi par Apple en ce moment - il semble qu'ils aient resserré quelque chose mais n'aient pas pris la peine de vérifier si cela cassait leurs exemples d'applications).

4voto

Bryan Points 2052

J'ai eu ce problème lorsque ma Nib a eu un UIViewController dans le fichier au niveau supérieur. Le chargement à partir de Nib a donc créé UIViewController puis j'ai essayé de l'utiliser à partir de ma classe, qui se trouvait dans la position de MapViewController dans votre code.

Dans mon cas, la solution consistait simplement à supprimer le fichier UIViewController à partir de mon fichier Nib.

0voto

Prince Points 16165

Vous devriez procéder de la manière suivante

MapViewController *mapView = [[MapViewController alloc] initWithNibName:@"MapViewController" bundle:nil];
UINavigationController *navCntrlr = [[UINavigationController alloc] initWithRootViewController:mapView];
mapView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
//hide navigation bar if needed
[self.navigationController presentModalViewController:navCntrlr animated:YES];
[mapView release];

0voto

binary star Points 81

Dans certains cas, il est peut-être préférable d'adopter une autre approche et de no supprimer l'UIViewController de la NIB, car, d'une part, en supprimant le contrôleur de vue de la hiérarchie de la NIB, on perd les marges d'Auto Layout.

Pourquoi ne pas laisser le UIViewController dans votre nib (.xib) et créer une sortie pour lui dans la classe propriétaire du fichier ? Ensuite, plutôt que d'instancier le contrôleur de vue directement dans votre code, chargez la nib avec la classe UINib et, au moment optimal (du point de vue de l'utilisation de la mémoire et des ressources), invoquez la méthode instantiateWithOwner() de l'instance nib pour désarchiver la NIB et connecter les objets nib aux sorties de la classe propriétaire.

    @IBOutlet var myViewController: myViewController?

    var nib : UINib?
    nib = UINib(nibName: "TheNib", bundle: nil)
    if (nib == nil) {
        println("could not load nib: TheNib.xib")
    }
    nib!.instantiateWithOwner(self, options: nil)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X