-
-
Save NatashaTheRobot/146e8ea387a9a2ef442939a79572ccac to your computer and use it in GitHub Desktop.
Bind Swift closure to StoryboardSegues (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
// StoryboardController.swift | |
// SegueIdentifier enumerates just the segue ID strings in the storyboard. VC's don't switch on this one... | |
enum SegueIdentifier: String { | |
case ShowDetail | |
} | |
// SegueInteractor binds closures to segues. VC's can switch on this instead! | |
enum SegueInteractor { | |
case ShowDetail((EventEntity) -> Void) | |
init(segue: UIStoryboardSegue) { | |
switch SegueIdentifier(rawValue: segue.identifier!)! { | |
case .ShowDetail: self = ShowDetail() { 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 "StoryboardController". This class 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: UIViewController { | |
lazy var tableViewModel: MasterTableViewModel: { /* etc... */ }() | |
// Source VC breaks Destination VC dependency! | |
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { | |
switch SegueInteractor(segue: segue) { | |
case .ShowDetail(let prepare): | |
prepare(tableViewModel.entityAtIndexPath(tableView.indexPathForSelectedRow!)) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment