How do you pass values to a VC in a segue

by Lou Franco

A theme I see a lot on StackOverflow is a developer makes a View Controller that collects some information from a user and wants to use it on a VC that they bring up in a segue.

Let's say you have a ViewController named FirstViewController, with the following outlet:

@IBOutlet var nameEdit: UITextField! = nil

And you have another ViewController named SecondViewController, with the following outlet:

@IBOutlet var nameLabel: UILabel! = nil

The idea is that the user types in their name on the first VC and the name is shown on a label in the second VC. If you made both of these VC's in your storyboard and even set up a segue there (perhaps connecting it to a button), you might be wondering how you get the value from the text edit into the label on the next VC.

The key is that before FirstViewController presents the SecondViewController it calls a method called prepare(for segue:sender:) which you can override, like this:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    guard let secondVC = segue.destination as? SecondViewController 
    else { return }

    // pass name to the VC
}

You might be tempted to write something like secondVC.nameLabel.text = self.nameEdit.text, but secondVC's outlets are not connected at this point. As is normal with storyboard connected VC classes, the outlets are set to nil to start and will be connected once viewDidLoad is called. At this point, the class has been inited, but it hasn't been loaded.

Instead, you need to add the following to SecondViewController

public var name: String? = nil

And, in prepare, you would add:

secondVC.name = self.nameEdit.text

And, then in SecondViewController.viewDidLoad, you would copy name to the label with:

self.nameLabel.text = self.name

Which would make sure that you only access nameLabel after it has been connected and is no longer nil.

Never miss a post

Get more tips like this in your inbox