-
-
Save msewell/5e185518a553b7ba9743451b5b817b31 to your computer and use it in GitHub Desktop.
| /* 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 | |
| } | |
| } |
When using an unwind segue, the segue identifier is nil.
Are you sure about that? I believe you can give your unwind segue an identifier in Interface Builder.
I could be doing something wrong here (xcode 9.1 swift 4) but if i write the performSegue method as you do
func performSegue(withIdentifier identifier: SegueIdentifier, sender: Any?) {
performSegue(withIdentifier: identifier.rawValue, sender: sender)
}
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 :)
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
}
}
}
@msewell, thanks for sharing your code.
When using an unwind segue, the segue identifier is
nil. The following modifications can take care of this while still catching missingSegueIdentifiercases.