Skip to content

Instantly share code, notes, and snippets.

@Winchariot
Created September 27, 2019 16:46
Show Gist options
  • Save Winchariot/7fbe4119015f8644b61654dd5bb826df to your computer and use it in GitHub Desktop.
Save Winchariot/7fbe4119015f8644b61654dd5bb826df to your computer and use it in GitHub Desktop.
VC Containment / Child View Controller hierarchy
import UIKit
//I represent a screen in my app that is relatively complicated. Suppose I'm a sort of scrollable activity feed in a financial app;
// I may have sections for balances, alerts, recent activity, credit score, a financial checkup quiz, etc.
// Separating those sections into their own child VCs is great for splitting up the workload and separating the code.
// Then I, the parent VC, can easily compose my feed using any subset of these child VCs and in any order using view controller containment.
class CompositeViewController: UIViewController {
private let scrollView: UIView?
private let contentView = UIView()
private let creditScoreVC = CreditScoreViewController()
private let balancesVC = BankAccountBalancesViewController()
private let myAlertsVC = MyAlertsViewController()
override func viewDidLoad() {
super.viewDidLoad()
scrollView = makeScrollView()
setupChildVCs([creditScoreVC, balancesVC, myAlertsVC], constrainedToBottomOf: nil)
}
private func makeScrollView() -> UIScrollView {
//create a UIScrollView; add + constrain contentView as its subview; return it
}
//Recursive function to contain an array of child View Controllers and lay them out vertically
private func setupChildVCs(_ childVCs: [UIViewController], constrainedToBottomOf viewAbove: UIView?) {
guard let childToAdd = childVCs.first, let childView = childToAdd.view else { return }
self.addChild(childToAdd)
contentView.addSubview(childView)
childView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
childView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
childView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
childView.topAnchor.constraint(equalTo: viewAbove?.bottomAnchor ?? contentView.topAnchor)
])
childToAdd.didMove(toParent: self)
let remainingChildVCs = Array(childVCs.dropFirst())
if remainingChildVCs.isEmpty {
NSLayoutConstraint.activate([childView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: 0)])
} else {
setupChildVCs(Array(childVCs.dropFirst()), constrainedToBottomOf: childView)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment