Swift version: 5.6
View controller containment allows you to embed one view controller inside another, which can simplify and organize your code. It takes four steps:
addChild()
on your parent view controller, passing in your child.didMove(toParent:)
on the child, passing in your main view controller.In Swift code it looks like this:
addChild(child)
child.view.frame = frame
view.addSubview(child.view)
child.didMove(toParent: self)
When you’re finished with it, the steps are conceptually similar but in reverse:
willMove(toParent:)
, passing in nil
.removeFromParent()
on the child.In code, it’s just three lines:
willMove(toParent: nil)
view.removeFromSuperview()
removeFromParent()
Just for convenience you might want to consider adding a small, private extension to UIViewController
to do these tasks for you – they do need to be run in a precise order, which is easily done incorrectly.
Something like this ought to do it:
@nonobjc extension UIViewController {
func add(_ child: UIViewController, frame: CGRect? = nil) {
addChild(child)
if let frame = frame {
child.view.frame = frame
}
view.addSubview(child.view)
child.didMove(toParent: self)
}
func remove() {
willMove(toParent: nil)
view.removeFromSuperview()
removeFromParent()
}
}
That’s marked @nonobjc
so it won’t conflict with any of Apple’s own code, now or in the future.
SPONSORED Still waiting on your CI build? Speed it up ~3x with Blaze - change one line, pay less, keep your existing GitHub workflows. First 25 HWS readers to use code HACKING at checkout get 50% off the first year. Try it now for free!
Sponsor Hacking with Swift and reach the world's largest Swift community!
Available from iOS 5.0 – learn more in my book Swift Design Patterns
This is part of the Swift Knowledge Base, a free, searchable collection of solutions for common iOS questions.
Link copied to your pasteboard.