How to add a Container View programmatically
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In UIKit, adding a container view programmatically usually means embedding one view controller inside another without using Interface Builder. The important part is not just adding a UIView. Proper containment requires adding the child view controller, attaching its view, setting constraints, and calling the lifecycle methods in the right order.
Container View Versus Child View Controller
A plain UIView can act as the visual container, but the real architectural feature is view-controller containment.
The correct sequence is:
- create or obtain the child view controller
- call
addChild - add the child view into a container
UIView - constrain the child view
- call
didMove(toParent:)
Skipping those steps can lead to broken lifecycle behavior.
A Working Example
This gives you a programmatic container view that hosts a full child controller.
Why addChild and didMove Matter
addChild tells UIKit that the parent now owns the child controller. didMove(toParent:) completes the transition.
Without this containment contract, appearance callbacks, trait propagation, and hierarchy behavior can be inconsistent.
That is why simply adding the child view as a subview is not enough when the child really is a controller.
Removing or Replacing a Child
If you later need to swap container content, remove the old child correctly.
This keeps the containment lifecycle balanced.
Storyboard Container View Versus Code
Interface Builder has a "Container View" object, but programmatic containment is more flexible when:
- the child controller type is chosen dynamically
- the layout depends on runtime state
- you want reusable embedding helpers in code
The UIKit rules are the same either way.
Common Layout Issues
Most bugs come from one of these:
- forgetting
translatesAutoresizingMaskIntoConstraints = false - constraining the child view incorrectly so it does not fill the container
- adding the child view before calling
addChild - forgetting
didMove(toParent:)
If the child controller appears visually but behaves strangely, check the containment sequence first.
When a Plain UIView Is Enough
Sometimes you only need a visual placeholder and not a real child controller. In that case, adding a plain UIView is enough and simpler.
The extra containment steps are required only when the embedded content is managed by another UIViewController. Keeping that distinction clear prevents overengineering small layouts.
Common Pitfalls
A common mistake is thinking a container view is just a decorated UIView. In UIKit architecture, the child controller relationship matters just as much as the view hierarchy.
Another mistake is embedding the child visually without calling the containment lifecycle methods, which can break appearance and parent-child behavior.
Developers also often forget the symmetric removal sequence when replacing the embedded controller.
Summary
- A programmatic container view is usually a
UIViewplus proper child-view-controller containment. - Use
addChild, add the view, apply constraints, then calldidMove(toParent:). - Make the child view fill the container with Auto Layout.
- Remove child controllers with
willMove,removeFromSuperview, andremoveFromParent. - The visual container and the controller lifecycle are both required for correct UIKit behavior.

