Last active
March 15, 2016 06:56
-
-
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
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
// | |
// 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