Search code examples
navigationseguexcode10swift4.2

Prepare doesn't get called on segue (Swift 4.2)


I've searched for an answer here, but wasn't able to find the exact same issue I have, please help me so sort it out.

The problem is that when I create a separate view and try to make a segue using storyboard and navigation view controller, the segue itself works fine, but

override func prepare(for segue: UIStoryboardSegue, sender: Any?)

does not get called. To make my example as minimal as possible I've make a toy app to show what's going on.

That's how the overall storyboard schema looks like. ViewController is embedded in NavigationController.

Segue is made with ctrl + SecondViewController, identifier is set.

Custom class for SecondViewController is set.

View controllers have the following implementation:
Main view controller sets the title of the only button:

class ViewController: UIViewController {

    @IBOutlet weak var button: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()

        button.setTitle("Awesome title", for: .normal)
    }
}

On button press the label is meant to be updated from the button's title:

class SecondViewController: UIViewController {
    @IBOutlet weak var label: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        print("SecondViewController viewDidLoad method")
    }

    // MARK: - Navigation

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        print(print("SecondViewController prepare method"))
        if let text = (sender as? UIButton)?.titleLabel?.text {
            label.text = text
        }
    }
}

I intentionally put two print statements to show that viewDidLoad actually gets called, but not prepare.

Here is a gif showing how the app works. As you may see label on the second view doesn't get updated either.

I've also tried to set segue this way, then create an @IBAction function and manually call performSegue:

@IBAction func onButton(_ sender: UIButton) {
    performSegue(withIdentifier: "Id", sender: self)
}

Please help me to understand and solve the problem. Thank you.


Solution

  • Ok, I figured out what's wrong. For those who still feel confused by the way segues work in IOS have a look at the diagram below:

    Segues in IOS (taken from here)

    Note that prepare (for: sender) is located in View A, not in View B. This is critical since it gets triggered before the actual segue is performed. Moreover, if you assign some values to View B parameter (for instance UIIMageView), then the view gets rendered considering these changes.