Created
September 27, 2019 16:46
-
-
Save Winchariot/7fbe4119015f8644b61654dd5bb826df to your computer and use it in GitHub Desktop.
VC Containment / Child View Controller hierarchy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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