Skip to content

Instantly share code, notes, and snippets.

@garohussenjian
Last active April 18, 2016 01:24
Show Gist options
  • Save garohussenjian/dab2eb94432b18e85fedd2adb1dbdfd9 to your computer and use it in GitHub Desktop.
Save garohussenjian/dab2eb94432b18e85fedd2adb1dbdfd9 to your computer and use it in GitHub Desktop.
Bind closure to Storyboard Segues (Master-Detail example)
// SegueInteractor.swift
// SegueIdentifier enumerates just the segue ID strings in the storyboard. VC's don't switch on this...
private enum SegueIdentifier: String {
case ShowDetail
}
// SegueInteractor binds closures to segues. VC's switch on this instead!
enum SegueInteractor {
case PrepareShowDetail((EventEntity) -> Void)
init(segue: UIStoryboardSegue) {
switch SegueIdentifier(rawValue: segue.identifier!)! {
case .ShowDetail: self = PrepareShowDetail() { segue.detailController.prepare($0) }
}
}
}
// This is to keep the segue init above nice and compact on one line.
// Add as many of these as needed to "SegueInteractor". This file might grow a bit,
// but should be limited to represent the containment structures in the associated storyboard.
extension UIStoryboardSegue {
var detailController: DetailViewController {
let nav = destinationViewController as! UINavigationController
return nav.topViewController as! DetailViewController
}
}
// DetailViewController.swift
class DetailViewController: UIViewController {
var event: EventEntity {
didSet {
// build view model / update view in viewWillAppear
}
}
}
extension DetailViewController {
// Destination VC defines a method to be bound to a SegueInteractor as a closure.
// Dependency injection happens here.
func prepare(event: EventEntity) {
self.event = event
// other vc (not view) setup can happen here if needed
}
}
// MasterViewController.swift
class MasterViewController: UITableViewController {
lazy var tableViewModel: MasterTableViewModel: { /* etc... */ }()
// Source VC avoids Destination VC dependency!
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
switch SegueInteractor(segue: segue) {
case .PrepareShowDetail(let prepare):
guard let selectedIndexPath = tableView.indexPathForSelectedRow else { fatalError("no selection") }
guard let eventEntity = tableViewModel.entityAtIndexPath(selectedIndexPath) else { fatalError("event entity not found") }
prepare(eventEntity)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment