Search code examples
iosswiftsegue

I am trying to Segue and pass a string, but I am getting an error


I am getting this error when I am trying to perform a segue to another view controller. I don't know why I am getting this error?

Thread 1: EXC_BAD_ACCESS

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "NormalPushupSegue" {
            let normalVC = segue.destination as! PopupViewController
            normalVC.formType = "Normal"
            performSegue(withIdentifier: "NormalPushupSegue", sender: self)
        }
        if segue.identifier == "DiamondPushupSegue" {
            let diamondVC = segue.destination as! PopupViewController
            diamondVC.formType = "Diamond"
            performSegue(withIdentifier: "DiamondPushupSegue", sender: self)
        }
        if segue.identifier == "WidePushupSegue" {
            let wideVC = segue.destination as! PopupViewController
            wideVC.formType = "Wide"
            performSegue(withIdentifier: "WidePushupSegue", sender: self)
        }
        if segue.identifier == "DeclinePushupSegue" {
            let declineVC = segue.destination as! PopupViewController
            declineVC.formType = "Decline"
            performSegue(withIdentifier: "DeclinePushupSegue", sender: self)
        }
    }

Solution

  • First of all it's better to safely unwrap your view controllers. Like so:

    if let myViewController = segue.destination as? MyViewController { 
        // Set up the VC, add some values and options
    }
    

    Second - you do not need to call performSegue , perform for segue is already calling your view controller. Just remove performSegue

    Third - you can make it easier and apply such logic:

    enum AppSegueName: String {
    case Normal = "NormalPushupSegue"
    case Diamond = "DiamondPushupSegue"
    case Wide = "WidePushupSegue"
    case Decline = "DeclinePushupSegue"
    }
    
    extension AppSegueName: CaseIterable {}
    

    And in prepare func use switch\case statement and compare AppSegueName raw value to segue.identifier

    like so:

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        AppSegueName.allCases.forEach {
            if $0.rawValue == segue.identifier {
    
                if let myViewController = segue.destination as? MyViewController { 
                myViewController.formType = $0 // formType is of type AppSegueName
                }
            }
        }
    }