Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save NatashaTheRobot/146e8ea387a9a2ef442939a79572ccac to your computer and use it in GitHub Desktop.
Save NatashaTheRobot/146e8ea387a9a2ef442939a79572ccac to your computer and use it in GitHub Desktop.
Bind Swift closure to StoryboardSegues (Master-Detail example)
// 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