Last active
October 3, 2022 16:45
-
-
Save msewell/5e185518a553b7ba9743451b5b817b31 to your computer and use it in GitHub Desktop.
SegueHandlerType for Swift 3
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
/* The SegueHandlerType pattern, as seen on [1, 2], adapted for the changed Swift 3 syntax. | |
[1] https://developer.apple.com/library/content/samplecode/Lister/Listings/Lister_SegueHandlerType_swift.html | |
[2] https://www.natashatherobot.com/protocol-oriented-segue-identifiers-swift/ | |
*/ | |
protocol SegueHandlerType { | |
// `typealias` has been changed to `associatedtype` for Protocols in Swift 3. | |
associatedtype SegueIdentifier: RawRepresentable | |
} | |
extension SegueHandlerType where Self: UIViewController, SegueIdentifier.RawValue == String { | |
// This used to be `performSegueWithIdentifier(...)`. | |
func performSegue(withIdentifier identifier: SegueIdentifier, sender: Any?) { | |
performSegue(withIdentifier: identifier.rawValue, sender: sender) | |
} | |
func segueIdentifier(for segue: UIStoryboardSegue) -> SegueIdentifier { | |
guard let identifier = segue.identifier, let segueIdentifier = SegueIdentifier(rawValue: identifier) else { | |
fatalError("Couldn't handle segue identifier \(String(describing: segue.identifier)) for view controller of type \(type(of: self)).") | |
} | |
return segueIdentifier | |
} | |
} | |
import UIKit | |
class ViewController: UIViewController { | |
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { | |
switch segueIdentifier(for: segue) { | |
case .showFoo: | |
// prepare for segue to Foo | |
break | |
case .showBar: | |
// prepare for segue to Bar | |
break | |
} | |
} | |
} | |
/* We're using a protocol extension here to separate UIViewController concerns. | |
See [1, 2] for more info on this. | |
[1] https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html#//apple_ref/doc/uid/TP40014097-CH25-ID521 | |
[2] https://www.natashatherobot.com/using-swift-extensions/ | |
*/ | |
extension ViewController: SegueHandlerType { | |
enum SegueIdentifier: String { | |
case showFoo | |
case showBar | |
} | |
} |
Hi, thanks for the gist !
the switch statement would be swiftier without the break statements
class ViewController: UIViewController {
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segueIdentifier(for: segue) {
case .showFoo:
// prepare for segue to Foo
case .showBar:
// prepare for segue to Bar
}
}
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I could be doing something wrong here (xcode 9.1 swift 4) but if i write the performSegue method as you do
then when t type this
performSegue(withIdentifier: .measurements , sender: self)
I got no autocomplete after typing the period. I would have to explicitly add SegueIdentifier. to get the autocomplete to kickin
if, in the protocol extension, I change the performSegue to a different form, say by replacing the withIdentifier to _ as here
func performSegue(_ identifier: SegueIdentifier, sender: Any?) { performSegue(withIdentifier: identifier.rawValue, sender: sender) }
then I don't need to type SegueIdentifier but just start with .m and the autocomplete kicks in
the lack of Xcode autocompleting is a downside bigger than the benefit of having a method with the same parameter names Imho.
Of course, this is possibly just another Xcode bug :)