Container ViewController
Basically, there are two types of view controllers: Content view controllers and container view controllers. Container view controllers are used to manage some set of content view controllers and present them as so-called child view controllers, whereas content view controllers are used to present – surprise – some content. Most of the times, container view controllers are without any relation to a specific content. Therefore, they are highly reusable. UIKit provides a rich set of container view controllers like UINavigationController, UITabBarController and UISplitViewController. However, if these controllers fulfill not your user interface requirements, you can create your own container view controller. UIKit supports this since iOS 5.
Hint: This post has been updated to Swift 3, Xcode 8 and iOS 10
Adding a Content View Controller as a Child View Controller
We have two view controllers: containerViewController and contentViewController. We want the containerViewController to present the contentViewController as a child view controller in a view called containerView. To accomplish this, the following steps needs to be done in containerViewController:
//STEP 1 contentViewController = ContentViewController(nibName: "ContentViewController", bundle: nil) if let contentViewController = contentViewController { //STEP 2 addChildViewController(contentViewController) //STEP 3 contentView.addSubview(contentViewController.view) //STEP 4 contentViewController.view.translatesAutoresizingMaskIntoConstraints = false contentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[view]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["view":contentViewController.view])) contentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[view]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["view":contentViewController.view])) //STEP 5 contentViewController.didMove(toParentViewController: self) }
Let’s go through the steps:
- The contentViewController is created. In this case, its view is loaded from a XIB.
- The contentViewController is added as a child view controller to the containerViewController. Only if this method is called, UIKit guarantees that all events on the child view controller will be called properly! In this call, UIKit automatically calls the method willMoveToParentViewController of the contentViewController . You can override this method, but don’t forget to call super!
- The view auf the contentViewController is added to a specific subview of the containerViewController – in this case it is a view called contentView , which is accessed through an outlet.
- In this step the appearance of the child view controller’s view is configured. In this case, we use auto layout constraints. Constraints to the top, left, bottom and top are set.
- The didMoveToParentViewController method of the contentViewController is called. Again, this method can be overridden.
After these steps, the contentViewController is is a proper child view controller of the containerViewController.
Removing a ChildViewController
If you want to remove a child view controller, there are also some things do to:
if let contentViewController = contentViewController { //STEP 1 contentViewController.willMove(toParentViewController: nil) //STEP 2 contentViewController.view.removeFromSuperview() //STEP 3 contentViewController.removeFromParentViewController() } contentViewController = nil
- First, the contentViewController ‘s method willMoveToParentViewController is called.
- The view of the contentViewController is removed.
- The contentViewController is removed from the parent view controller. UIKit automatically calls the didMoveToParentViewController method of the contentViewController with nil as an argument.
Again, only if these actions are taken, the view controller is properly removed.
Conclusion
If you have specific requirements, that can not be handled by UIKit’s container view controllers, you can build your own container view controller. However, it is very important to do this properly to prevent hard to find bugs.
References
Title image: @ Alex Kolokythas Photography / shutterstock.com