I’m developing an iPad application that has a navigation menu similar to a web site: imagine a menu on the left of the screen with a series of button and each time you tap on a button a different controller is shown.
I can’t use any of the container controllers provided by the os due to some graphic constraints, so I decided to write my own container class similar in concept to a UITabBarController. I would like to know if the method I used is correct, in particular the usage of addChildViewController: and didMoveToParentViewController:
In the init of my container I do this:
MAHomeController *home = [[MAHomeController alloc] initWithNibName:@"MAHomeController" bundle:nil];
[self addChildViewController:home];
[home didMoveToParentViewController:self];
homeIndex = [self.childViewControllers indexOfObject:home];
[home release];
MAConfigHomeController *config = [[MAConfigHomeController alloc] initWithNibName:@"MAConfigHomeController" bundle:nil];
[self addChildViewController:config];
[config didMoveToParentViewController:self];
configIndex = [self.childViewControllers indexOfObject:config];
[config release];
MAViewerHomeController *viewer = [[MAViewerHomeController alloc] initWithNibName:@"MAViewerHomeController" bundle:nil];
[self addChildViewController:viewer];
[viewer didMoveToParentViewController:self];
viewerIndex = [self.childViewControllers indexOfObject:viewer];
[viewer release];
As you can see I add all the content controllers at once, and call didMoveToParentViewController: immediately after adding them. Is this ok?
Then the method that handles the navigation between the content does something like this:
// some stuff removed for brevity, mostly configuration stuff
UIViewController *fromCtrl = [self.childViewControllers objectAtIndex:currentIndex];
UIViewController *toCtrl = [self.childViewControllers objectAtIndex:index];
self.currentIndex = index;
[self transitionFromViewController:fromCtrl toViewController:toCtrl duration:0.7 options:opts animations:^(void) {} completion:^(BOOL finished) {
if (completion)
completion();
}];
As you can see in the completion block, I don’t call didMoveToParentViewController: on the newly transitioned controller, because it was added before to the childViewControllers of the container. And neither do I remove the old controller because in fact it stays in the childViewCOntrollers array until the container controller is dealloced.
All the events are routed correctly, even to child controllers nested inside the 3 main ones. Also memory should not be a problem, because with a simulated memory warning the views of the not-visible controllers are unloaded and reloaded when displayed.
Is this design ok?
If you read through the View Controller guide on the iOS development center, there is no constrain on addChildViewController: and didMoveToParentViewController: that would make the order of what you are doing incorrect.
The only thing I would do different is potentially delaying this so that iOS does not load the nibs until you actually show the view. I bet you if you run the profiler you will be loading all the nibs when you init your parent container.