Search code examples
objective-cuicontainerviewprogrammatically-createdchildviewcontroller

Container View Controller Programmatically


I have been researching this for a while but can't quite find what I need. I would like to learn how to create a container view with a child view controller programmatically. I'm still fairly new to this and learning the basics, but from what I gather, this used to be done using resuable views and attaching them to child view controllers prior to the container view object being added to the library (right?), I am looking for either a tutorial or example code that shows how to do it from scratch, using xib's, but without any complications, like adding table cells etc... Just the container and the child programmatically. Does that make sense? I'm sure there must be something on S.O. Thanks if you can help.

UPDATE ---------------------------------------------------------------------------------------------------------------------- I have managed to create a child view controller that appears with a UIButton action. Relevant code:

- (IBAction)Pressed:(id)sender {
    ChildViewController *childViewController = [[ChildViewController alloc]init];
    [self displayContentController:childViewController];
}

- (void) displayContentController: (UIViewController*) content {
    [self addChildViewController:content];
    content.view.frame = CGRectMake(0, 115, 320, 240);
    content.view.backgroundColor = [UIColor redColor];

        CATransition *transition = [CATransition animation];
transition.duration = 1;
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromLeft;
[transition setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[content.view.layer addAnimation:transition forKey:nil];
[self.view addSubview:content.view];
[content didMoveToParentViewController:self];
}

So that's working fine. I click the button and a red square, child view controller, occupying a small part of the screen appears. What I would like to know is if this is best practice.


Solution

  • Basically this involves having 1 Parent View Controller who'll orchestrate the appearance of his child view controllers.

    To be honest, I find the Apple Docs quite complete on this part.

    Quote from the same docs :

    Adding a Child View Controller to Your Content

    To incorporate a child view controller into your content programmatically, create a parent-child relationship between the relevant view controllers by doing the following:

    1. Call the addChildViewController: method of your container view controller. This method tells UIKit that your container view controller is now managing the view of the child view controller.
    2. Add the child’s root view to your container’s view hierarchy. Always remember to set the size and position of the child’s frame as part of this process.
    3. Add any constraints for managing the size and position of the child’s root view.
    4. Call the didMoveToParentViewController: method of the child view controller.

    Codesample :

    - (void) displayContentController: (UIViewController*) content {
       [self addChildViewController:content];
       content.view.frame = [self frameForContentController];
       [self.view addSubview:self.currentClientView];
       [content didMoveToParentViewController:self];
    }
    

    Responding to update about best practices :

    Objc.io has some pretty neat articles in this regard.

    For example, the article talking about View Controller Containment notes :

    View controllers should be reusable and self-contained entities.

    Child view controllers are no exception to this rule of thumb. In order to achieve this, the parent view controller should only be concerned with two tasks: laying out the child view controller’s root view, and communicating with the child view controller through its exposed API. It should never modify the child’s view tree or other internal state directly.

    Child view controllers should contain the necessary logic to manage their view trees themselves – don’t treat them as dumb views. This will result in a clearer separation of concerns and better reusability.

    They also talk about transitions between view controllers while using this pattern.