web-dev-qa-db-fra.com

Comment fonctionne View Controller Containment dans iOS 5?

Dans WWDC 2011 Session 102, Apple a introduit View Controller Containment, qui permet de créer des conteneurs de contrôleur de vue personnalisés, analogues à UITabBarController, UINavigationController et au comme.

J'ai regardé les exemples plusieurs fois. De nombreuses méthodes sont associées à ce modèle, mais il était un peu difficile de les comprendre exactement. Je vais poster ici ce que je pense qui se passe et voir si la communauté va confirmer ou infirmer mes soupçons.

Scénario 1: passage d'un parent à un nouveau contrôleur de vue parent

[vc willMoveToParentViewController:self];
[self addChildViewController:vc];
[self.view addSubview:vc.view]; // or something like this.
[vc didMoveToParentViewController:self];

Les deux premières lignes doivent-elles apparaître dans l’ordre donné ou peuvent-elles être inversées?

Scénario 2: passage d'un contrôleur de vue parent à aucun contrôleur de vue parent

[vc willMoveToParentViewController:nil];
[vc.view removeFromSuperview];
[vc removeFromParentViewController];

Est-il également nécessaire d'appeler [vc didMoveToParentViewController:nil]? Les exemples de la session 102 ne faisaient pas cela dans ce scénario, mais je ne sais pas s'il s'agissait d'une omission ou non.

Scénario 3: Passage d’un contrôleur de vue parent à un autre

Cela se produira probablement de la manière suivante, car la logique de chaque contrôleur de vue parent sera encapsulée.

// In the old parent
[vc willMoveToParentViewController:nil];
[vc.view removeFromSuperview];
[vc removeFromParentViewController];

// In the new parent
[vc willMoveToParentViewController:self];
[self addChildViewController:vc];
[self.view addSubview:vc.view];
[vc didMoveToParentViewController:self];

Questions

Ma question principale est la suivante: est-ce ainsi que le confinement du contrôleur de vue devrait fonctionner, en général? Les mécanismes indiqués ci-dessus sont-ils corrects?

Est-il nécessaire d'appeler willMoveToParentViewController avant d'appeler addChildViewController? Cela me semble être l’ordre logique, mais est-ce strictement nécessaire?

Est-il nécessaire d'appeler didMoveToParentViewController:nil après avoir appelé removeFromParentViewController?

107
Gregory Higley

Les documents UIViewController indiquent clairement quand et quand ne pas appeler les méthodes willMove/didMove. Consultez la documentation "Implémentation d'un contrôleur de vue de conteneur" .

Les docs disent que si vous ne remplacez pas addChildViewController, vous n’avez pas à appeler willMoveToParentViewController: méthode. Cependant, vous devez appeler le didMoveToParentViewController: méthode une fois la transition terminée. "De même, il incombe au contrôleur de la vue du conteneur d’appeler le willMoveToParentViewController: avant d’appeler la méthode removeFromParentViewController. La méthode removeFromParentViewController appelle le didMoveToParentViewController: méthode du contrôleur de vue enfant. "

En outre, il existe un exemple élaboré ici et un exemple de code ici .

Bonne chance

73
timthetoolman

Cette partie n'est pas correcte:

[vc willMoveToParentViewController:self];
[self addChildViewController:vc];
[self.view addSubview:vc.view]; // or something like this.
[vc didMoveToParentViewController:self];

Selon la documentation:

Lorsque votre conteneur personnalisé appelle la méthode addChildViewController:, il appelle automatiquement la méthode willMoveToParentViewController: du contrôleur de vue à ajouter en tant qu'enfant avant de l'ajouter.

Donc, vous n'avez pas besoin du [vc willMoveToParentViewController:self] appel. Cela se fait automatiquement lorsque vous appelez [self addChildViewController:vc]. Voici à nouveau l'exemple de code:

[self addChildViewController:vc];
// [vc willMoveToParentViewController:self] called automatically
[self.view addSubview:vc.view]; // or something like this.
[vc didMoveToParentViewController:self];

Pour supprimer les contrôleurs de vue:

La méthode removeFromParentViewController appelle automatiquement la méthode didMoveToParentViewController: du contrôleur de vue enfant après avoir supprimé l'enfant.

Vraisemblablement, cet appel est [oldVC didMoveToParentViewController:nil].

[vc willMoveToParentViewController:nil];
[vc.view removeFromSuperview];
[vc removeFromParentViewController];
// [vc didMoveToParentViewController:nil] called automatically
22
nevan king