Skip to content

Instantly share code, notes, and snippets.

@miguelfermin
Last active March 15, 2016 06:56
Show Gist options
  • Save miguelfermin/41df792d756e52e8a1db to your computer and use it in GitHub Desktop.
Save miguelfermin/41df792d756e52e8a1db to your computer and use it in GitHub Desktop.
MAFSegueHandlerType: This protocol implements best Swift practices to simplify the use of segues throuhout the app
//
// MAFSegueHandlerType.swift
// MAFFinance
//
// Created by Miguel Fermin on 8/1/15.
// Copyright © 2015 Miguel Fermin. All rights reserved.
//
import UIKit
/// Provides convenient syntax to work with storyboard segues.
///
/// This protocol implements best Swift practices to simplify the use of segues throuhout the app.
/// Benefits of using this approach:
/// * Compiler errors when adding new segues if the new case isn't handled
/// * Reusable
/// * Convenient syntax
/// * Tighen app constrains using protocols with associate types
/// * Share implementation through a constrained protocol extension
protocol MAFSegueHandlerType {
typealias MAFSegueIdentifier: RawRepresentable
}
extension MAFSegueHandlerType where Self: UIViewController, MAFSegueIdentifier.RawValue == String {
/// Initiates the segue with the specified MAFSegueIdentifier from the current view controller'€™s storyboard file.
///
/// This method wraps UIViewControlle's **"performSegueWithIdentifier:sender:"** method but uses the convenient MAFSegueIdentifier to
/// provide a concise syntax and be reusable throughout the app.
/// - parameter segueIdentifier: The MAFSegueIdentifier enum type that identifies the triggered segue.
/// - parameter sender: The object that you want to use to initiate the segue. This object is made available for informational purposes during the actual segue.
func performSegueWithIdentifier(segueIdentifier: MAFSegueIdentifier, sender: AnyObject?) {
performSegueWithIdentifier(segueIdentifier.rawValue, sender: sender)
}
/// Extracts the passed segue's identifier, wraps it in a MAFSegueIdentifier enum type, and returns it.
/// - parameter segue: The segue to extract the **segue.identifier** from.
/// - returns: A MAFSegueIdentifier enum type representing the segue's identifier.
func segueIdentifierForSegue(segue: UIStoryboardSegue) -> MAFSegueIdentifier {
guard let identifier = segue.identifier, let segueIdentifier = MAFSegueIdentifier(rawValue: identifier)
else { fatalError("Invalid segue identifier \(segue.identifier)") }
return segueIdentifier
}
/// Gets and returns the segue's destination UINavigationController's topViewController.
/// - important: This method should only be used when you want the modalPresentationStyle set to **CurrentContext** on iPad.
/// - parameter segue: The segue to get the navigation controller's topViewController from.
/// - returns: The segue's destination UINavigationController's topViewController.
func navigationTopViewControllerFromSegue(segue: UIStoryboardSegue) -> UIViewController {
let navigationController = (segue.destinationViewController as! UINavigationController)
// Set the modalPresentationStyle to CurrentContext on iPad only. If this is set on iPhone,
// the keyboard would cover the textfields positioned at the lower side of the screen.
if (UIDevice.currentDevice().userInterfaceIdiom == UIUserInterfaceIdiom.Pad) {
navigationController.modalPresentationStyle = UIModalPresentationStyle.CurrentContext
}
return navigationController.topViewController!
}
}
/* How to use it */
// Conform to "MAFSegueHandlerType" in your view controller
class MAFViewController: MAFDetailViewController, MAFSegueHandlerType {... }
// Then you must implement the "MAFSegueIdentifier" enum as follows:
enum MAFSegueIdentifier: String {
case ShowJobEditor = "ShowJobEditor"
case ShowAddPaycheck = "ShowAddPaycheck"
case ShowAllPaychecks = "ShowAllPaychecks"
}
// Notice that "ShowJobEditor", "ShowAddPaycheck", and "ShowAllPaychecks" should be set on a storyboard
// This leads to the following prepareForSegue implementation:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
switch segueIdentifierForSegue(segue) {
case .ShowJobEditor:
// Config...
case .ShowAddPaycheck:
// Config...
case .ShowAllPaychecks:
// Config...
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment