Search code examples
swiftsegue

Why doesn't performSegue() call shouldPerformSegue()


Quite new to programming in Swift and mobile development in general. I am trying to use performSegue() and control it without if-else statements. I made a google search how to use override func shouldPerformSegue() and tried to implement it in different ways but none of them solved my situation. Here I need to segue to Yellow or Green views if the switch is on using corresponding buttons. Even if I made return false, the function does not cancel the segue to happen. What is the reason of this behaviour and how can I fix it? Many thanks.

class ViewController: UIViewController {
    
    @IBOutlet var segueSwitch: UISwitch!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    
    @IBAction func yellowButtonTapped(_ button: UIButton) {
        performSegue(withIdentifier: "Yellow", sender: nil)
    }
    
    @IBAction func greenButtonTapped(_ button: UIButton) {
        performSegue(withIdentifier: "Green", sender: nil)
    }
    
    override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
        // return segueSwitch.isOn
        return false
    }
    
}

storyboard


Solution

  • shouldPerformSegue does not get called if you use performSegue(withIdentifier: in code. This function only get called if the segue is triggered from storyboard.

    You can easily test this by adding 2 Buttons to a ViewController in storyboard one with the storyboard segue and one with an IBOutlet to a new ViewController. Then add a print statement to shouldPerformSegue. In the Button outlet call performSegue. Only the first button performing the segue from storyboard will print to the console.

    And additionally you don´t need it. Any validation you would perform in shouldPerformSegue can be done in the ...ButtonTapped function:

    @IBAction func yellowButtonTapped(_ button: UIButton) {
        if validateSegue(){
            performSegue(withIdentifier: "Yellow", sender: nil)
        }
    }
    
    override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
        validateSegue()
    }
    
    func validateSegue() -> Bool{
        ......
    }