Skip to content

Instantly share code, notes, and snippets.

@BohdanOrlov
Created October 23, 2017 09:36
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save BohdanOrlov/e4be8299454469b201d10b0594f03964 to your computer and use it in GitHub Desktop.
Save BohdanOrlov/e4be8299454469b201d10b0594f03964 to your computer and use it in GitHub Desktop.
Swift implementation of idea that manny view controller can do light work: http://khanlou.com/2016/02/many-controllers/
public protocol ViewControllerLifecycleBehavior {
func afterLoading(_ viewController: UIViewController)
func beforeAppearing(_ viewController: UIViewController)
func afterAppearing(_ viewController: UIViewController)
func beforeDisappearing(_ viewController: UIViewController)
func afterDisappearing(_ viewController: UIViewController)
func beforeLayingOutSubviews(_ viewController: UIViewController)
func afterLayingOutSubviews(_ viewController: UIViewController)
}
extension ViewControllerLifecycleBehavior {
public func afterLoading(_ viewController: UIViewController) {}
public func beforeAppearing(_ viewController: UIViewController) {}
public func afterAppearing(_ viewController: UIViewController) {}
public func beforeDisappearing(_ viewController: UIViewController) {}
public func afterDisappearing(_ viewController: UIViewController) {}
public func beforeLayingOutSubviews(_ viewController: UIViewController) {}
public func afterLayingOutSubviews(_ viewController: UIViewController) {}
}
public extension UIViewController {
/*
Add behaviors to be hooked into this view controller’s lifecycle.
This method requires the view controller’s view to be loaded, so it’s best to call
in `viewDidLoad` to avoid it being loaded prematurely.
- parameter behaviors: Behaviors to be added.
*/
public func add(behaviors: [ViewControllerLifecycleBehavior]) {
let behaviorViewController = LifecycleBehaviorViewController(behaviors: behaviors, behaviorsHost: self)
self.add(behaviorViewController: behaviorViewController)
}
private func add(behaviorViewController: LifecycleBehaviorViewController) {
self.addChildViewController(behaviorViewController)
self.view.addSubview(behaviorViewController.view)
behaviorViewController.didMove(toParentViewController: self)
}
}
fileprivate final class LifecycleBehaviorViewController: UIViewController {
private unowned let behaviorsHost: UIViewController
private let behaviors: [ViewControllerLifecycleBehavior]
// MARK: - Initialization
init(behaviors: [ViewControllerLifecycleBehavior], behaviorsHost: UIViewController) {
self.behaviorsHost = behaviorsHost
self.behaviors = behaviors
super.init(nibName: nil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - UIViewController
override func viewDidLoad() {
super.viewDidLoad()
view.isHidden = true
for behavior in self.behaviors {
behavior.afterLoading(self.behaviorsHost)
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
for behavior in self.behaviors {
behavior.beforeAppearing(self.behaviorsHost)
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
for behavior in self.behaviors {
behavior.afterAppearing(self.behaviorsHost)
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
for behavior in self.behaviors {
behavior.beforeDisappearing(self.behaviorsHost)
}
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
for behavior in self.behaviors {
behavior.afterDisappearing(self.behaviorsHost)
}
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
for behavior in self.behaviors {
behavior.beforeLayingOutSubviews(self.behaviorsHost)
}
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
for behavior in self.behaviors {
behavior.afterLayingOutSubviews(self.behaviorsHost)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment