Created
September 2, 2016 23:47
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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