Je me lance juste pour la première fois dans le développement iOS, et l'une des premières choses que j'ai eu à faire est d'implémenter un contrôleur de vue de conteneur personnalisé - appelons-le SideBarViewController
- qui permute lequel de plusieurs contrôleurs de vue enfants possibles il montre, presque exactement comme un contrôleur de barre d'onglets standard . (C'est à peu près un contrôleur de barre d'onglets mais avec un menu latéral masquable au lieu d'une barre d'onglets.)
Conformément aux instructions de la documentation Apple, j'appelle addChildViewController
chaque fois que j'ajoute un ViewController enfant à mon conteneur. Mon code pour échanger le contrôleur de vue enfant actuel affiché par le SideBarViewController
ressemble à ceci:
- (void)showViewController:(UIViewController *)newViewController {
UIViewController* oldViewController = [self.childViewControllers
objectAtIndex:0];
[oldViewController removeFromParentViewController];
[oldViewController.view removeFromSuperview];
newViewController.view.frame = CGRectMake(
0, 0, self.view.frame.size.width, self.view.frame.size.height
);
[self addChildViewController: newViewController];
[self.view addSubview: newViewController.view];
}
Ensuite, j'ai commencé à essayer de comprendre ce que addChildViewController
fait ici et j'ai réalisé que je n'en avais aucune idée. En plus de coller le nouveau ViewController
dans le .childViewControllers
tableau, il semble n'avoir aucun effet sur quoi que ce soit. Les actions et les prises de la vue du contrôleur enfant vers le contrôleur enfant que j'ai défini sur le storyboard fonctionnent toujours très bien même si je n'appelle jamais addChildViewController
, et je ne peux pas imaginer ce que cela pourrait affecter d'autre.
En effet, si je réécris mon code pour ne pas appeler addChildViewController
, et plutôt ressembler à ça ...
- (void)showViewController:(UIViewController *)newViewController {
// Get the current child from a member variable of `SideBarViewController`
UIViewController* oldViewController = currentChildViewController;
[oldViewController.view removeFromSuperview];
newViewController.view.frame = CGRectMake(
0, 0, self.view.frame.size.width, self.view.frame.size.height
);
[self.view addSubview: newViewController.view];
currentChildViewController = newViewController;
}
... alors mon application fonctionne toujours parfaitement, pour autant que je sache!
La documentation Apple n'éclaire pas beaucoup sur ce que addChildViewController
fait, ou pourquoi nous sommes censés l'appeler. Toute l'étendue de la description pertinente de ce que fait la méthode ou pourquoi elle devrait être utilisée dans sa section dans la UIViewController
référence de classe est, à l'heure actuelle:
Ajoute le contrôleur de vue donné en tant qu'enfant. ... Cette méthode est uniquement destinée à être appelée par une implémentation d'un contrôleur de vue de conteneur personnalisé. Si vous remplacez cette méthode, vous devez appeler super dans votre implémentation.
Il y a aussi ce paragraphe plus tôt sur la même page:
Votre contrôleur de vue de conteneur doit associer un contrôleur de vue enfant à lui-même avant d'ajouter la vue racine de l'enfant à la hiérarchie de vues. Cela permet à iOS d'acheminer correctement les événements vers les contrôleurs de vue enfants et les vues que ces contrôleurs gèrent. De même, après avoir supprimé la vue racine d'un enfant de sa hiérarchie de vues, il doit déconnecter ce contrôleur de vue enfant de lui-même. Pour créer ou annuler ces associations, votre conteneur appelle des méthodes spécifiques définies par la classe de base. Ces méthodes ne sont pas destinées à être appelées par les clients de votre classe de conteneur; ils doivent être utilisés uniquement par l'implémentation de votre conteneur pour fournir le comportement de confinement attendu.
Voici les méthodes essentielles que vous pourriez avoir besoin d'appeler:
addChildViewController:
removeFromParentViewController
willMoveToParentViewController:
didMoveToParentViewController:
mais il n'offre aucun indice sur ce que sont les «événements» ou le «comportement de confinement attendu» dont il parle, ni pourquoi (ou même quand) appeler ces méthodes est «essentiel».
Les exemples de contrôleurs de vue de conteneur personnalisés dans la section "Contrôleurs de vue de conteneur personnalisés" de la documentation Apple appellent tous cette méthode, donc je suppose qu'elle sert un objectif important au-delà de simplement faire apparaître le ViewController enfant sur un tableau, mais je ne peux pas comprendre quel est cet objectif. Que fait cette méthode et pourquoi devrais-je l'appeler?