Search code examples
iosswiftchildviewcontrollerstackview

iOS : Why do we need to add child view controller when adding view as subview does the work?


There is a ViewController1 which has a stackView. I created an instance of ViewController2 and added it's view as a subview to the stackView of ViewController1, I wanted to see if only by doing this does viewDidLoad of ViewController2 is invoked and it did so, ViewController2 viewDidLoad was invoked when I added view of ViewController2 to stackView of ViewController1. For ex: In ViewController1self.stackView.addArrangedSubView(viewControler2.view) Then why do we need to do addChild(viewController2) then add view as subview, those typical lines which adds childController and it's view in parent view controller hierarchy


Solution

  • Certainly viewDidLoad was called. That happened instantly as soon as you referred to ViewController2's view in your code.

    But let's say your ViewController2 does other things besides load a view. Suppose its view contains a button that is hooked through an action to a function in ViewController2. If you now tap that button nothing happens.

    That's because the ViewController2 itself is dead: it has vanished in a puff of smoke.

    You can see that by implementing deinit in ViewController2. You will see that, just as viewDidLoad is called, so is deinit. You are left with a view controller's view that has no view controller. That is bad.

    There is a view controller hierarchy that is responsible for maintaining relations between view controllers. When you add ViewController2 as a child view controller of ViewController1, you maintain that hierarchy, and you maintain it correctly according to the rules, which say:

    If VC2's view is somewhere inside VC1's view, then VC2 needs to be a child (at some depth) of VC1.

    In other words, the view hierarchy and the view controller hierarchy must run together. Otherwise, the responder chain will break and life will become chaos.


    (There are other requirements when you make one view controller the child of another, like sending didMoveToParent to the child as part of the opening dance, along with other message forwarding responsibilities later, so as to ensure that the child view controller gets other messages like viewDidAppear at the right time. It's a complex business. However, I've focussed my answer on the very basic part of what you asked.)


    I should add: if your goal was merely to fetch a view out of a nib and stuff it into your own view, you can certainly do that, no problem. What you must not do is use a view controller as a kind of magnet or vacuum cleaner to fetch a view for you if your intention is then to let go of the view controller itself.