Skip to content

Instantly share code, notes, and snippets.

@sharplet
Created February 6, 2019 16:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sharplet/26cd42811792d0f90f49487f381f837d to your computer and use it in GitHub Desktop.
Save sharplet/26cd42811792d0f90f49487f381f837d to your computer and use it in GitHub Desktop.
A protocol for view controllers with a replaceable content view controller
import UIKit
/// For a view controller that has no content of its own, implement like so:
///
/// extension RootViewController: ContentViewEmbedding {
/// var contentView: UIView! {
/// return view
/// }
/// }
protocol ContentViewEmbedding {
var contentView: UIView! { get }
}
extension ContentViewEmbedding where Self: UIViewController {
func removeContentViewController() {
guard let vc = childViewControllers.first(where: { $0.view.isDescendant(of: contentView) }) else { return }
vc.willMove(toParentViewController: nil)
vc.view.removeFromSuperview()
vc.removeFromParentViewController()
}
func replaceContentViewController(with vc: UIViewController, animated: Bool) {
let duration = animated ? 0.2 : 0
if let currentChild = childViewControllers.first {
currentChild.willMove(toParentViewController: nil)
addChildViewController(vc)
contentView.embedSubview(vc.view)
UIView.transition(
with: contentView,
duration: duration,
options: [.transitionCrossDissolve],
animations: setNeedsStatusBarAppearanceUpdate,
completion: { _ in
currentChild.view.removeFromSuperview()
currentChild.removeFromParentViewController()
vc.didMove(toParentViewController: self)
}
)
} else {
addChildViewController(vc)
contentView.embedSubview(vc.view)
vc.didMove(toParentViewController: self)
}
}
}
extension UIViewController {
@available(*, unavailable, message: "Please conform to 'ContentViewEmbedding'.")
func removeContentViewController() {}
@available(*, unavailable, message: "Please conform to 'ContentViewEmbedding'.")
func replaceContentViewController(with _: UIViewController, animated _: Bool) {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment