Last active
April 18, 2016 01:24
-
-
Save garohussenjian/dab2eb94432b18e85fedd2adb1dbdfd9 to your computer and use it in GitHub Desktop.
Bind closure to Storyboard Segues (Master-Detail example)
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
// 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