Passing Data Between Views – A Swift Way to Get Into iOS Development #2

Number two of my tutorial series on iOS Development. Today we are going to pass information between view controllers. More precisely, we will ask for an input and display it on the next view controller.

Where to Start?

In the last tutorial we learned how to get started with a new project in Xcode. So create a new project. I’ll name mine PassingData and we’re set.
If you forgot how to set up a new project here’s the link to the previous tutorial.
How to set up a new project.

passing-data-new-project
In future tutorial we will always start at this point. So make yourself familiar with creating new projects.

 

One Controller is not enough!

Now we’re going to set up our UI so we have something to work with. First you switch to your Main.storyboard file. The editor automatically switches to the Interface Builder.

passing-.data-interface-builder
The standard Main.storyboard contains one empty view controller. Not enough for our purposes.

Focus on the Object Library in the lower right corner. You can see the first element is a view controller, that’s exactly what we need so go on and drag it into the Interface Builder, right next to our first view controller.

passing-data-object-library
We want another view controller. Because this kind of object is used so often it is displayed as one of the first items.

Right now we have two view controllers in our Storyboard. But we have no way to manipulate or interact with them. So let’s add some object which allow the user to do something.

Two Buttons, a Text Field and a Label.

We are selecting our first view controller on the left. Now we can add a button and a text field to the view. As you are already familiar with the Object Library drag a button and a text field on our view controller. Place the button in the middle of the view, close to the top. Xcode will show you some guide lines when aligning the button. The text field goes dead center, like our label last time. You should now have something like this.

passing-data-user-interface
The button and the text field allow the user to interact with our app.

After that we now have to make sure that the UI looks right on every device. Last time we covered constraints so put a Horizontally Centered constraint on the button. The text field gets a Horizontally Centered and a Vertically Centered constraint. (Small hint: you can find those in the bottom bar, the icon with the two left-aligned rectangles).

Today were are going to get a little bit deeper into constraints. Because there is a lot more you can do with it than just centering objects. Select the button and press the icon right next to the two rectangles.

passing-data-advanced-constraints
You can set how far an object should be away from the nearest neighbor on every side. Height and width can also be fixed.

Because we want the button to be fixed at the top we activate the top constraint with a constant distance of 0. Then hit Add 1 Constraint.

passing-data-constraint-settings
A lot of options are available to make your UI adapt to every display. The activated constraints are shown by a solid red line.

What’s that orange frame? Did I break something?

Now let’s do the same with our text field. But now we are going to set the left and right constraints to 10 respectively. You might see that an object gets surrounded by an orange frame. The orange frame is displayed every time the current object doesn’t correspond to the set constraints. You can get rid of it by pressing the icon left to our two rectangles in the bottom bar. It updates the current objects dimensions and displays it correctly. This can also be used as a UI-Debugging tool, because it let’s you see how an object will be displayed on the screen.

passing-data-orange-frame
The orange frame around the text field shows how it will be displayed on a real device.
passing-data-constraint-icons
The first button on the left let’s you update the objects frame size.

If you look at the button the it is not very descriptive in what it does. So let’s change that. First select the button and make sure your Utilities section is displayed (remember the one on the right). The Utilities section also has a lot to offer. For the time being we are going to use the Attributes inspector (4th from the left)

passing-data-button-properties
You can set a lot of the obejcts attributes in the Interface Builder. However, all of them can be set in code as well.

Now to change the text that is displayed just change the text field with Button in it. After you hit enter the button gets updated with the new text.

For the text field we are going to set a Placeholder text. The approach is the same. Select the text field and under Placeholder Text write “Your name goes here!”, because we will ask the user to tell us their name. Don’t forget to also change the text alignment to center to make things look a little bit tidier.

And that’s it for the first view controller. Now onto the our second one.

passing-data-finished-view-controller
Now that we are done with the first view controller we can go to the second one.

Two is a pair!

The SecondViewController is laid out the same way the first one is. One key difference is that we don’t want to have a text field in our SecondViewController. We will use a Label, like we did last time. So go ahead. Add the button to the top, the label to the center and fix it all in place with constraints.

After you are done your SecondViewController should look like this.

passing-data-second-view-controller
The second one is nearly identical to the first one. But only nearly.

 Using Segues. No, not the ones you stand on.

Now that we have our two view controllers we can think about how to switch between those two. Luckily, there is a way to do that without a single bit of code.

First you make sure that both view controllers are visible in your Interface Builder. Then you select the first button. And like you did last time when we wanted to connect our Label to our code you Ctrl + Click and Drag onto the SecondViewController.

You will see a line that follows your cursor and once you are over the SecondViewController and let go you get a popup. The popup lets you choose how the transition should be animated. We want the SecondViewController to completely replace our other one, so choose Show Detail.

passing-data-segues
Segues are the iOS-way of changing between view controllers.

Now repeat the same for the button on the SecondViewController to allow us to get back to the first one.

All in all your could run your app right now and it would correctly switch between the two view controllers. But we want to pass data between the two.

For that to work we need to be able to identify each segue. To accomplish that just select one segue and in the Utilities section, und the Attributes Inspector tab, you should see an empty text field that says identifier. Give it a reasonable name like “goToSecondViewControllerSegue” and hit enter.

passing-data-segues
Segues have less properties you can set. You could for example code your own segue animation and use it here.

The second one doesn’t necessarily need an identifier because we won’t pass data from the second to the first ViewController.

Hooking everything up.

Now we have to hook up our UI with our codebase. If you followed closely you might noticed that we have a ViewController.swift file but no file for our SecondViewController. So let’s add one.

By right clicking on the folder name PassingData in your Navigator you can choose New File. Xcode lets you then choose from a list of templates. We want to control a ViewController with our file so we want a CocoaTouch Class. The next view shows certain details you can set for your file. We want it to be a subclass of UIViewController. A subclass inherits all the functions and properties of its “Parent” or “Super” but it also gives you the ability to change and tweak it for your own purposes. We name our file SecondViewController and hit next. We can then choose where to save the file. The standard save directory is your projects folder.

passing-data-new-file
Adding a new file is as simple as it can be. There are some templates you can choose from or start with a blank .swift file.

Now we switch back to our Main.storyboard and we select the SecondViewController. In the Utilities section we switch to the tab left of the Attributes Inspector. Now under custom class we replace the greyed out UIViewController with our custom class SecondViewController and hit enter.

Now the file is connected to our SecondViewController.

Same procedure as last year time.

In the first tutorial you learned how to connect UI elements to your code. So go ahead and connect the TextField to the ViewController.swift file and the Label to the SecondViewController.swift file. We don’t need to connect the buttons because they already do what we want. If your Assistant Editor does not let you create a new outlet in the SecondViewController.swift file press Cmd + B to build your project. After you’ve done this is should work properly.

Preparing the SecondViewController.

Before we can pass data from one ViewController to the other we have to make sure we have a variable to save the incoming data. So select your SecondViewController.swift to add some code.

We also introduce a new function to your knowledge base. It is called viewWillAppear() and it is called every time before a view gets displayed. Unlike the viewDidLoad() which only gets called once the view is loaded into memory.

(1)    var name: String = ""
        
    override func viewWillAppear(_ animated: Bool) {
(2)     if name.isEmpty {
(3)         myLabel.text = "Hello, nice to meet you!"
        } else {
(4)         myLabel.text = "Hello \(name), nice to meet you!"
        } 
    }
  1. We declare an empty variable called name. We will use it later to store the incoming data.
  2. We check if the name is empty or not.
  3. If its the case we set the label to a generic ouput. Because it seems like the user hasn’t put anything in the TextField.
  4. If the user put a something in the TextField we want to display it. So we use something called String Interpolation to add the value of a variable to a string. You can simply write “\(variableName)” to use String Interpolation.

Passing data to SecondViewController.

Now we switch to our ViewController.swift file. We now have to handle the user input correctly. Firstly we introduce a new function called prepare( ). This function gets called every time before the app executes a segue. So this is the perfect place to pass the data to the upcoming ViewController.

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
(1)     switch segue.identifier! {
(2)         case "goToSecondViewControllerSegue":
(3)             if let nameText = textField.text {
(4)                 let destVC = segue.destination as! SecondViewController
(5)                 destVC.name = nameText
                }
(6)         default:
                print("No action specified!")
        }
    }
  1. A switch statement is like a lot of if statements. It’s just a condensed way of representing it. You also need to have a default statement.
  2. Inside the switch statements you can have cases. Each case acts like an if-statement.
  3. This line automatically unwrap our optional variable, unwrapping is necessary to work with the variable. The property text is an optional variable because the TextField could also be empty.
  4. The segue object also contains the ViewController that will replace the current one. It is stored in the property destination. The “as! SecondViewController” part lets you use the variable with all the properties you have specified in the SecondViewController class.
  5. Now we set the name property of our destVC to our nameText.
  6. To cover all other segues that might be added we have a default case. This does not do anything besides writing “No action specified!” to the console.

And then we’re done!
You can now run your app and try it out.

 

passing-data-first-view-controller-app
The first ViewController takes your name as input and passes it to the second one …
passing-data-second-view-controller-app
… and the second ViewController takes this data and displays it for you. How nice!

What you have learned today.

Today you learned a valuable lesson. How to pass data, i.e. objects from one ViewController to another one. You got familiar with new UI elements like a Button or a TextField. We also build upon our knowledge of constraints so you can now lay out your apps even more precisely. You learned about how to use Segues to switch between two ViewControllers. Creating a new file which inherits from a Superclass is also something we covered today. Two new functions have been introduced in this tutorial viewWillAppear() and prepare(). And in the end you got to know how String Interpolation works and how we handle passing data in code.

Not enough?

As always if you are still curious try to build upon the current project. Add some TextFields and display them in different Labels on the SecondViewController.

 

Happy Coding!

Michael.

 

All the files of the finished project can be downloaded here.

 


Did you find this tutorial helpful?
Do you want to learn more about iOS and all its in and outs?
Tell me in the comments what you would like to see covered.

Leave a Reply