skip to Main Content

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)
  }
      
}

2

Answers


  1. 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) {
    
    
              }
        }
    }
        
    
    Login or Signup to reply.
  2. 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)
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search