All problems in computer science can be solved by another level of indirection - David Wheller
override func traitCollectionDidChange(_ previousTraits: UITraintCollection?) {
super.traitCollectionDidChange(previousTraits)
if previousTraits?.horizontalSizeClass != traitCollection.horinontalSizeClass {
switch traitCollection.horizontalSizeClass {
case .compact:
setupConstraintsForCompactEnvironment()
case .unspecified:
fallthrough
case .regular:
setupConstraintsForRegularEnvironment()
}
}
}
class SimpleExampleViewController: UIViewController {
@IBOutlet var stackView: UIStackView!
override func viewWillLayoutSubviews() {
let size = view.bounds.size
let useWideDesign = size.width >= size.height
if useWideDesign {
stackView.axis = .horizontal
} else {
stacView.axis = .vertical
}
}
}
override func viewWillTransition(to size: CGSize,
with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWlllTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: { _ in
stackView.transform = CGAffineTransform(scaleX: 1.4, y: 1.4)
}, completion: { _ in
UIView.animate(withDuration: 0.5, animations: {
stackView.transform = CGAffineTransform.identity
})
})
}
class ExampleContainerViewController: UIViewController {
var elementViewControllers: [UIViewController?] = [nil, nil , nil]
var displayedDesign: Design? = nil
override func viewWillLayoutSubviews() {
let size = view.bounds.size
let newDesign = decideDesign(size)
if displayedDesign != newDesign {
applyDesign(newDesign)
displayedDesign = newDesign
}
}
private func decideDesign(_ size: CGSize) -> Design {
let axis: UILayoutConstraintAxis
if size.width > size.height {
axis = .horizontal
} else {
axis = .vertical
}
let elementKind: Design.ElementKind
let widthThreshold = CGFloat(750)
if size.width < widthThreshold {
elementKind = .small
} else {
elementKind = .large
}
return Design(axis: axis, elementKind: elementKind)
}
private func applyDesign(_ newDesign: Design) {
stackView.axis = newDesign.axis
if displayedDesign?.elementKind != newDesign.elementKind {
for (index, elementViewController) in elementViewControllers.enumerated() {
if let oldElementViewController = elementViewController {
removeOldElementViewController(oldElementViewController)
}
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let newElementViewController = storyboard.instantiateViewController(withIdentifiner: newDesign.elementIdentifier)
addNewElementViewController(newElementViewController)
elementViewControllers[index] = newElementViewController
}
}
}
// 각 메소드의 순서가 중요하다.
private func addNewElementViewController(_ elementViewController: UIViewController) {
addChildViewController(elementViewController)
stackView.addArrangedSubview(elementviewController.view)
elementViewController.didMove(toParentViewController: self)
}
private func removeOldElementViewController(_ elementViewController: UIViewController) {
elementViewController.willMove(toParentViewController: nil)
elementViewController.view.removeFromSuperView()
elementViewController.removeFromParentViewController()
}
}