How would I go about extending an NSObject, NSStoryboardSegue.Identifier
, to provide a set of cases as potential parameter types?
extension NSStoryboardSegue.Identifier {
enum identifier: String {
case showHelpWindow
}
}
extension ViewController {
override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
if (segue.identifier == "showHelpWindow") {
// What I have now
}
if segue.identifier == .showHelpWindow {
// What I'm trying to get
}
}
func showHelpWindow() {
// What I have now
performSegue(withIdentifier: "showHelpWindow", sender: self)
// What I'm trying to get
performSegue(withIdentifier: .showHelpWindow, sender: self)
}
}
CodePudding user response:
Define a protocol
protocol SegueHandlerType {
associatedtype SegueIdentifier : RawRepresentable
}
and a protocol extension to overload performSegue
. The segueIdentifer(for
method is to get the identifier if there are multiple segues in the controller
extension SegueHandlerType where Self : UIViewController, SegueIdentifier.RawValue == String {
func performSegue(withIdentifier segueIdentifier : SegueIdentifier, sender: Any?) {
performSegue(withIdentifier: segueIdentifier.rawValue, sender: sender)
}
func segueIdentifer(for segue : UIStoryboardSegue) -> SegueIdentifier {
guard let identifier = segue.identifier, let segueIdentifier = SegueIdentifier(rawValue: identifier) else {
fatalError("Invalid segue identifier \(segue.identifier!)")
}
return segueIdentifier
}
}
To use it adopt the protocol in the view controller and declare an enum for the identifiers
class ViewController: UIViewController, SegueHandlerType {
enum SegueIdentifier : String {
case showHelpWindow, showSomethingElse
}
...
func showHelpWindow() {
performSegue(withIdentifier: .showHelpWindow, sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if case .showHelpWindow = segueIdentifer(for:segue) {
}
}
}
CodePudding user response:
You don't actually need to extend NSStoryboardSegue.Identifier
at all. Just create your own enum:
enum SegueIdentifier: String {
case mySegue
}
Add a custom ==
operator so that it can be compared with segue.identifier
:
static func ==(lhs: String?, rhs: SegueIdentifier) -> Bool {
lhs == rhs.rawValue
}
Then extend NSViewController
to add an overload of performSegue
that takes SegueIdentifier
:
extension NSViewController {
func performSegue(withIdentifier identifier: SegueIdentifier, sender: Any?) {
performSegue(withIdentifier: identifier.rawValue, sender: sender)
}
}
Usage:
class MyViewController: NSViewController {
override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
if segue.identifier == .mySegue {
// ...
}
}
func foo() {
performSegue(withIdentifier: .mySegue, sender: nil)
}
}