I just watched a 2011 WWDC
presentation on "Implementing UIViewController Containment" (here's a link to the video)
They mentioned both of these ways of adding viewControllers to the screen, and I would appreciate some clarification on best practices...
addChildViewController / removeFromParentViewController
used with an @property (nonatomic, readonly) NSArray *childViewControllers and [self transitionFromViewController:currentView toViewController:nextView duration: options: animations: completion:];
pushViewController: animated: / popViewControllerAnimated
they really quickly skimmed past this in the presentation
In my apps I use all custom viewControllers, and until today I have always managed them with:
[nextController performSelector:@selector(setDelegate:) withObject:self];
[currentPageController.view removeFromSuperview];
[self.view addSubview:nextController.view];
But I understand now that this is bad practice, and I'm wondering what is the correct way to use "addChildViewController" and what is the correct way to use "pushViewController"?
I really appreciate your thoughts on the matter!
Yes, pushViewController:
is for navigation controllers that manage a stack of view controllers. addChildViewController:
on the other hand is part of an iOS 5 feature called "view controller containment".
The basic idea behind this is that you can embed your view controllers into other view controllers of your own (e.g. when porting an iPhone app to the iPad) and thus easily do your own implementation of things like navigation controllers, split view controllers etc.
One problem with an implementation like the one you show is that you only handle views. View controller events like orientation changes will not be passed properly down the hierarchy. View controller containment tries to ensure that all contained view controllers will get the appropriate messages, too.
Looking at your implementation you should also think about what you really want to achieve by this. A navigation controller may be the right thing or you might even show the next controller modally (see https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/PresentingaViewController.html) A bonus when using these methods (e.g. navigation controllers and modal views) is that the user is already familiar with those navigation techniques.
In any case https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/ is a good read about how to transition between view controllers.
When using view controller containment you basically have to add the view to the containing view as usual (this has to be done even if the controller is added). Then you use addChildViewController:
to add the child view controller to the surrounding one. You also have to notify the child controller by didMoveToParentViewController:
that it has been put into another controller. You can also use transitionFromViewController:toViewController:
to exchange one view controller for another, optionally giving an animation.