iosswiftpresentviewcontroller

What is the difference between presenting a ViewController vs adding a ViewController as a child


I just read an interesting article that introduced me to a new concept that I have never heard before, which is adding a ViewController as a child of another ViewController. The article uses the UIActivityIndicatorView as an example to demonstrate a common use for when to use the addChild method and this got me wondering why would you use that method instead of just presenting the view controller.

The part I don't fully understand is the benefit of using that specific method since both presenting and adding as a child could be modular in a way that they can be reusable.

When would you use addChild instead of just presenting it? When does that make sense?

addChild:

let parent = UIViewController()
let child = MyViewController()

parent.view.addSubview(child.view)
parent.addChild(child)
child.didMove(toParent: parent)

Present:

let storyboard : UIStoryboard = UIStoryboard(name: "StoryboardName", bundle:nil)
let myVC  = storyboard.instantiateViewController(withIdentifier: "myViewController") as! MyViewController
self.present(myVC , animated: true, completion: nil)

Solution

  • The difference is that when you present a controller, it becomes modal, and when you add it as a child controller, it doesn't. The difference is in semantics and use cases.

    Modal

    As an example of modal window, imagine a window with an OK button in macOS that prevents you from interacting with the parent window until you close it.

    Hence why there can be only one view controller presented by a particular controller: the presented controller becomes “main” for user interaction, and the user must close it to return to the parent window.

    A typical example of a modal window is an alert.

    Child

    But a child view controller is a different story. There can be any amount of them on a particular VC.

    The parent controller becomes sort of container for child view controllers. For example, there can be a dashboard with multiple panels, and each panel can be a separate controller. This allows to separate logic between different pieces of an application instead of cramming everything into a single controller, to implement user customization in easy way, etc.

    A typical example of a parent-child controller interaction is UINavigationController: the navigation controller is the parent, and all view controllers pushed into it are its children. We don't make an uber controller with the whole application's logic, we separate it between different screens, and the navigation controller is only responsible for presentation.