Skip to content

Instantly share code, notes, and snippets.

@jakecraige
Created September 2, 2016 23:47
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 jakecraige/8e3636b523bb479d6baaefd3e497fdca to your computer and use it in GitHub Desktop.
Save jakecraige/8e3636b523bb479d6baaefd3e497fdca to your computer and use it in GitHub Desktop.
Example of how to use a protocol where you might normally use a superclass. This is also more flexible because you can mix it into anything, even if you don't have control of the superclass.
import UIKit
import XCPlayground
// MARK: Implementation
protocol Page {
var name: String { get }
var details: String { get }
var asViewController: UIViewController { get }
}
extension Page where Self: UIViewController {
var asViewController: UIViewController {
return self
}
}
// MARK: Protocol Conformance
final class ViewController: UIViewController, Page {
let name: String = "View Controller"
let details: String = "A regular view controller."
}
final class TableViewController: UITableViewController, Page {
let name: String = "Table View Controller"
let details: String = "A table view controller."
}
// MARK: Usage
final class MainViewController: UIViewController {
let stackView = UIStackView()
let nameLabel = UILabel()
let detailsLabel = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
setupViews()
}
func loadPage(page: Page) {
nameLabel.text = page.name
detailsLabel.text = page.details
let vc = page.asViewController
addChildViewController(vc)
stackView.insertArrangedSubview(vc.view, atIndex: 2)
vc.didMoveToParentViewController(self)
}
private func setupViews() {
view.backgroundColor = .whiteColor()
nameLabel.font = .boldSystemFontOfSize(32)
detailsLabel.font = .systemFontOfSize(20)
stackView.axis = .Vertical
stackView.frame = view.frame
stackView.addArrangedSubview(nameLabel)
stackView.addArrangedSubview(detailsLabel)
view.addSubview(stackView)
}
}
let vc = MainViewController()
vc.view.frame = CGRect(x: 0, y: 0, width: 375, height: 667)
XCPlaygroundPage.currentPage.liveView = vc.view
let regularVC = ViewController()
let tableVC = TableViewController()
// We can pass in the regular view controller, or the table view controller to `loadPage`, which takes the `Page` type.
// Via the protocol, we've also enforced that it can be turned into a view controller, without having to do anything extra
// on the types that implement it.
vc.loadPage(regularVC)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment