Building complex screens with child ViewControllers
class StackViewController: UIViewController {
private let scrollView = UIScrollView()
private let stackView = UIStackView()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(scrollView)
scrollView.addSubview(stackView)
setupConstraints()
stackView.axis = .vertical
}
private func setupConstraints() {
scrollView.translatesAutoresizingMaskIntoConstraints = false
stackView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
scrollView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
stackView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
stackView.topAnchor.constraint(equalTo: scrollView.topAnchor),
stackView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
stackView.widthAnchor.constraint(equalTo: view.safeAreaLayoutGuide.widthAnchor)
])
}
}
extension StackViewController {
func add(_ child: UIViewController) {
addChild(child)
stackView.addArrangedSubview(child.view)
child.didMove(toParent: self)
}
func remove(_ child: UIViewController) {
guard child.parent != nil else {
return
}
child.willMove(toParent: nil)
stackView.removeArrangedSubview(child.view)
child.view.removeFromSuperview()
child.removeFromParent()
}
}
// Usage example:
class DayViewController: StackViewController {
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
}
private func setupUI() {
let today = Date()
let calendarVC = CalendarViewController(date: today)
calendarVC.delegate = self
add(calendarVC)
add(SummaryViewController(date: today))
add(SleepViewController(date: today))
add(WorkoutViewController(date: today))
}
}
extension DayViewController: CalendarViewControllDelegate {
func dateSelected(_ date: Date) {
reloadDay(with: date)
}
}