Jan 192013
 

iOS5 added something a lot of iOS developers have been needing, container view controllers. This lets you put a view controller inside another view controller. This is wonderful for countless reasons, but the one that draws me is reuse and abstraction.

I was working on a app which had 2 similar windows, they had a top part (body) and a footer. The top part was easy, they each had their own UIViewControllers. But when I went to add the footer to the second one I got to thinking DRY, I was repeating myself and that’s never a good idea. So I abstracted out a parent class and I went to put the footer code in and I got stuck, I wanted my footers to also be view controllers.

I remembered a talk I attended about new iOS5 features and container view controllers was mentioned. After a bit of googling around I had it.

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    // set up the footer contained view, this has nothing to do with table footers, this is below
    // the tableview
    //
    FooterViewController *vc = [[FooterViewController alloc] initWithNibName:@"FooterViewController"  bundle:nil];
    vc.view.frame = self.footerFPOView.frame;
    vc.delegate = self;
    
    [self addChildViewController:vc];
    [vc didMoveToParentViewController:self];
    [self.view addSubview: vc.view];
}

Of course there are a few things to note. First, hooray, I’m loading my footer from a xib file. I’ve placed a UIVIew called footerFPOView in the outer view controller’s xib, this is a trick I use all the time. FPO stands for For Position Only and that lets me use interface builder for positioning. I communicate with a protocol, hence the delegate. And then I call addChildViewController to add it, and then I tell the new one that it has a new parent, and finally, add its view.

This is just a few lines of code yet the window should respond to both view controllers and respond to rotations.