How to Pass Data Between iOS Views in Swift.


  • Share on Pinterest

This tutorial will walk you through the process of passing data from one view to another in an iOS application using Swift. Let's get started!

There are a few steps to the process but once done you will see it is pretty simple to do provided you get everything in place. I am going to step over a few of the details that I think by now you should be familiar with like creating a new project, outlets, and actions. If these are still a little new to you I strongly recommend looking through some of my other articles that cover those topics and more

First, create a new Swift based iOS project with a single view to keep the code base to a minimum and allow us to focus on the details we are really interested in.

Now create a second view controller by searching and dragging one from the object library (lower right panel, third icon). We will pass two simple strings between the views, so for the first viewController add two text entry fields and a button. For the second add two labels to display the text entered on the first view.

To pass the data and switch views we use a segue, (I have added an extra step here in case I want to do anything extra when the button is clicked), right-click the button and drag to the second view controller and release. From the popup menu select Action Segue > show, this sets up the segue to take place when the button is pressed. See the video below if you need extra help to make sense of it.

Make sure you are using the first view controller and open the assistant editor (the second icon on the right-hand side of the Xcode icon bar), you should see the viewController.swift file appear. Right-click and drag from the first text entry field to the controller code and create an @IBOutlet named ‘fieldA', then do the same with the second text entry field and name it ‘fieldB'. I also added an @IBAction for the button but it is not needed for the segue to take place, I just added it in case I want to do some extra things when it is clicked. The code for the view controller should now look something like this.

The icon that you see between the two views is called a segue, you will most likely end up using more than one in an application so for that reason I strongly recommend naming them all so they can be uniquely identified in code. So go ahead and click on the segue icon and in the right hand side attributes view, give it the name ‘btnSubmitSegue' as seen in the screenshot below.

For the second viewController, we are going to create our own UIViewController class as the one provided has a lot of code that you just do not need to be confused with at this time! So in the file menu create a new iOS Cocoa Touch Class.

06 - New iOS Cocoa Touch Class

I named my class ‘SecondViewController', make sure you have the language set to Swift.

07 - SecondViewController Class Creation

Next we need to assign our new custom view controller class to our view, to do that select the second view controller and in the right-hand identity inspector panel under ‘Custom Class' in the field named ‘Class' enter the name of the file you just created, in my case ‘SecondViewController', you should notice as you start typing it that autocomplete will try and help you out. A little side tip here is that Xcode is great at trying to help you complete many things, so if you find autocomplete is not working then it might be a sign you got something wrong.

The assistant editor for the second view controller should now be showing the nice clean version of our new class file. Right-click on the labels in the view and one by one drag to the code window to create two new @IBOutlets called labelA and labelB. These will be used to reference the text labels on the view and populate them with the entries from the first screen.

Now we need to add some properties to our second viewController class so that we can assign our data from the first view during the segue and hand it off to the new view. To do that create two variables, see the screenshot below. For simplicity, I called my two variables (one per display label) ‘firstDataPassed' and ‘secondDataPassed'. Note that you will often hear this technique called ‘Dependency Injection'.

Now the next step (yes I know it seems like a lot of steps!) is to create code that assigns (injects) the entry field text to our variables in the second view, we do this by overriding something called prepareForSegue in the first viewController. As the name suggests we are overriding the default with our code, copy and paste or enter the code below in ‘ViewController.swift' and see the screenshot for reference.

override func prepare (for segue: UIStoryboardSegue, sender: Any!) {
    if (segue.identifier == "btnSubmitSegue") {
        let svc = segue.destination as! SecondViewController
        svc.firstDataPassed = fieldA.text
        svc.secondDataPassed = fieldB.text
    }
}

Finally! In our second viewController class file (secondViewController.swift) we need to assign the variables to the display labels when the viewDidLoad is called. This is straight forward, just look for the override func viewDidLoad() and enter the code below (again see screenshot for reference).

labelA.text = firstDataPassed
labelB.text = secondDataPassed

We are done! You have reached the rainbow, run the simulator and enter some text into the two fields then hit the button, the second view should load showing the text you entered.

Hopefully, this has cleared up some of the mystery for you and set you on a path to multi-view happiness!

  • edel
    Author
    edel edel

    Hi there i really like the tutorial- I was wondering would you ever consider publishing one which shows how to segue between multiple tableviews or perhaps a collection view to a tableview? Have been looking for a tutorial in this in swift… so to give you an idea of what i mean …
    Creating a collection view that goes to another table view and then gives more detail on the subject?
    e.g.
    collectionview 1
    DOG
    CAT
    SNAKE

    select DOG and you get a tableview showing
    LABRADOR
    HUSKEY
    POODLE

    select LABRADOR
    and you get an individual view controller showing information on labradors

    and equally you could select CAT to get a list of different breeds then more information etc. etc.

    Would really appreciate any help you could give me on the above topic- finding it really hard to grasp and apply

    thanks

    • Peter Witham
      Author
      Peter Witham Peter Witham

      Hi Edel,

      An excellent question, I will add this to my list of things to look into. I have not seen anyone showing something along these lines and I do like a challenge 🙂

      I will let you know if I come up with a solution for you or find anyone else posting something along the lines of your suggestion.

      Peter.

      • edel
        Author
        edel edel

        Many Thanks! I was hoping to create an app like the iTunes music store where u can click on an album and a tableview appears…

  • harsh
    Author
    harsh harsh

    thank you very much

    • Peter Witham
      Author
      Peter Witham Peter Witham

      You are most welcome, thank you.

  • Jeremy Andrews
    Author
    Jeremy Andrews Jeremy Andrews

    Sorry – dumb question – but how do I access the variables in:
    override func viewDidLoad() {
    super.viewDidLoad()
    labelA.text = dataPassed
    labelB.text = secondDataPassed
    Thank you very much for a great Tut I learnt a lot its just that I need to add my variables from one scene to an array created in the next scene, the array eventually to be written to a file.

    • Peter Witham
      Author
      Peter Witham Peter Witham

      Hi Jeremy, thanks for the question and I’m glad this helped you down the path.

      Are you referring to dataPassed and secondDataPassed? Those are sent in the prepareForSegue function so you could just as easily use an array to pass there.

      If you mean accessing them outside of this function then you can simply push these variables into your array in the second controller inside this function.

      If I misunderstood the question please reply and I’ll try again 🙂

      Peter.

      • Jeremy Andrews
        Author
        Jeremy Andrews Jeremy Andrews

        Peter thanks so much for a prompt to the point reply.

        It is the accessing outside the function that I am struggling with. Its probably basic stuff that I should revise but if you can shortcut that for me I would be very grateful.
        what I have tried is as follows;
        class SecondViewController: UIViewController {

        @IBOutlet weak var labelA: UILabel!
        @IBOutlet weak var labelB: UILabel!

        var dataPassed:String!
        var secondDataPassed:String!
        var newvar:String!
        override func viewDidLoad() {
        super.viewDidLoad()

        labelA.text = dataPassed
        labelB.text = secondDataPassed
        newvar = dataPassed
        println(newvar)

        }
        println(newvar) gives “expected declaration”
        Am I missing something??

        • Peter Witham
          Author
          Peter Witham Peter Witham

          Hmmmm I ran a quick test here and it worked, try checking that the values you are sending make it to the second view controller. Does dataPassed and secondDataPassed have values?

  • Jeremy Andrews
    Author
    Jeremy Andrews Jeremy Andrews

    I have obviously missed something – here is the full second. Your help would be great.
    SecondViewController.swift
    // PassVar
    //
    // Created by A&CO Mac Mini on 2015/06/12.
    // Copyright (c) 2015 A&CO Mac Mini. All rights reserved.
    //

    import UIKit

    class SecondViewController: UIViewController {

    @IBOutlet weak var labelA: UILabel!
    @IBOutlet weak var labelB: UILabel!

    var dataPassed:String!
    var secondDataPassed:String!
    var newvar: String!
    var newvar2: String!

    override func viewDidLoad() {
    super.viewDidLoad()

    labelA.text = dataPassed
    labelB.text = secondDataPassed
    newvar = dataPassed
    newvar2 = secondDataPassed

    println(newvar + newvar2)

    }

    //println(newvar)
    // println(newvar2)

    override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
    }

    }

    Just in case here is my ViewController

    import UIKit

    class ViewController: UIViewController {

    override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
    }
    @IBOutlet weak var fieldA: UITextField!
    @IBOutlet weak var fieldB: UITextField!
    @IBAction func btnSubmit(sender: AnyObject) {
    }
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
    if (segue.identifier == “btnSubmitSegue”) {
    var svc = segue.destinationViewController as! SecondViewController;
    svc.dataPassed = fieldA.text
    svc.secondDataPassed = fieldB.text

    }
    }

    }
    Just in case here is my:
    import UIKit

    class ViewController: UIViewController {

    override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
    }
    @IBOutlet weak var fieldA: UITextField!
    @IBOutlet weak var fieldB: UITextField!
    @IBAction func btnSubmit(sender: AnyObject) {
    }
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
    if (segue.identifier == “btnSubmitSegue”) {
    var svc = segue.destinationViewController as! SecondViewController;
    svc.dataPassed = fieldA.text
    svc.secondDataPassed = fieldB.text

    }
    }

    }

  • Peter Witham
    Author
    Peter Witham Peter Witham

    Hi Jeremy,

    I have updated the post with a link to a sample project you can download (it’s at the bottom of the post). Hopefully this will give you a direct comparison to your version.

    Peter.

  • Jeremy Andrews
    Author
    Jeremy Andrews Jeremy Andrews

    Many thanks

    • Peter Witham
      Author
      Peter Witham Peter Witham

      Let me know how it goes!

  • Jeremy Andrews
    Author
    Jeremy Andrews Jeremy Andrews

    Stupid me – the answer simply was a button and an IBaction function like so:
    @IBAction func press(sender: AnyObject) {
    var newVar = dataPassed
    println(newVar)
    }
    I guess I could do it all in the viewDidLoad function

    I just missed the point that everything has to happen in functions – playground is a bit misleading in this respect

    • Peter Witham
      Author
      Peter Witham Peter Witham

      I am so glad to hear you got it working Jeremy! I bet you will do it without even thinking about it next time 🙂

  • Jeremy Andrews
    Author
    Jeremy Andrews Jeremy Andrews

    Thanks for the help

    • Peter Witham
      Author
      Peter Witham Peter Witham

      You are most welcome, I am glad to of helped someone reach a goal. That is my reason for sharing!

  • Joe Bentivegna
    Author
    Joe Bentivegna Joe Bentivegna

    Peter,

    Thank you so much. I tried 3 sites to figure this out until I found yours. Not only did it work, but I actually understood what you were saying!

    Regards
    Joe Bentivegna

    • Peter Witham
      Author
      Peter Witham Peter Witham

      Thanks Joe, I try to break things down to a point where I feel it will help the most amount of people 🙂

  • Sam
    Author
    Sam Sam

    Thanks Peter this has really helped me solve a seemingly simple issue! Very well written and easy to follow.

    • Peter Witham
      Author
      Peter Witham Peter Witham

      Thanks Sam, I am so glad to hear it helped you out. You have made my day!

      Peter.

  • Daniel Garofalo
    Author
    Daniel Garofalo Daniel Garofalo

    Hi Peter,
    Thanks so much for the help.
    The only thing I am having trouble with is having the label fields populate after I press my button. I get segued to the second view controller, but my the page is blank, the labels aren’t being filled. I downloaded your project, and it worked, however, when I deleted your segue, and replaced it with my own, I’m getting the same issue. I am ctrl+dragging my button onto the second view controller and choosing a show action. Any idea what I am doing wrong?

    Thanks,
    Dan G.

    • Peter Witham
      Author
      Peter Witham Peter Witham

      Hi Daniel,

      Firstly Thanks. Are you remembering to set an ID name for the segue when you create it?

      Regards,
      Peter.

  • Fabrice
    Author
    Fabrice Fabrice

    Hello very interesting tutorial. Is it possible to use the same process to create a list of favorites in a tableWiew. For example in my app have pages, each page a button and add to favorites, then find all the bookmarks added to a table.

    Thank you for your tutorials

    • Peter Witham
      Author
      Peter Witham Peter Witham

      Thank you for the question and comments.

      You could certainly use this technique for many different things including your scenario. This tutorial shows how the transport of data works, you can send anything you want including an array of favorites.

  • Scott A
    Author
    Scott A Scott A

    I am having an issue where my variable from a timer is not passing from one view to the other.

    View 1 – driveViewController:
    //
    // driveViewController.swift
    // NEW1
    //
    // Created by SA on 3/20/16.
    // Copyright © 2016 SA. All rights reserved.
    //

    import UIKit

    class driveViewController: UIViewController {

    var timer = NSTimer()

    var time = 0

    func result() {

    time++

    print(time)

    let min = Int(time/60)

    let sec = time – (60 * min)

    timerLabel.text = “\(min) m \(String(sec)) s”

    }

    @IBOutlet weak var timerLabel: UILabel!

    override func viewDidLoad() {
    super.viewDidLoad()

    timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector(“result”), userInfo: nil, repeats: true)

    }

    @IBAction func endDriveButton(sender: AnyObject) {

    timer.invalidate()

    print(timerLabel.text!)

    }

    override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()

    func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
    if (segue.identifier == “endDriveSegue”) {
    let svc = segue!.destinationViewController as! recordViewController;

    svc.toPass = timerLabel.text!

    }

    }

    }

    }

    View 2 – recordViewController

    //
    // recordViewController.swift
    // NEW1
    //
    // Created by SA on 3/20/16.
    // Copyright © 2016 SA. All rights reserved.
    //

    import UIKit

    class recordViewController: UIViewController {

    @IBOutlet weak var driveRecordLabel: UILabel!

    var toPass: String!

    override func viewDidLoad() {
    super.viewDidLoad()

    driveRecordLabel.text = toPass
    print(driveRecordLabel)

    }

    override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()

    }

    }

    I used a print to see in xcode what was being seen by the variable driveRecordVariable and it returns:
    <UILabel: 0x7fbc2c848cb0; frame = (20 123; 335 41); opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = >

    So I am clearly missing something here…any help would be greatly appreciated.

    • Peter Witham
      Author
      Peter Witham Peter Witham

      I noticed a couple of things with regards to the prepareForSegue, there is no override and it is nested in the didRecieveMemoryWarning, try replacing with this and be sure to not nest the function inside any other.


      override func prepareForSegue(segue: UIStoryBoardSegue, sender: AnyObject?) {
      If (segue.identifier == "endDriveSegue") {
      Let svc = segue.destinationViewController as! recordViewController
      svc.toPass = timerLabel.text!
      }
      }

  • swathi bala
    Author
    swathi bala swathi bala

    Hello ! Being a first time ios developer, found this tutorial very informative and useful. Clear explanation and very well written ! Thanks a lot !

    • Peter Witham
      Author
      Peter Witham Peter Witham

      Thank you, I am happy to hear it helped you out.

  • Fabrice
    Author
    Fabrice Fabrice

    Hello, thank you for this tuto very interesting. I tried to apply your method to pass a text and an image from a view to a tableview. Frankly I have not arrived there does not happen. Do you have any advice. thank you

    • Peter Witham
      Author
      Peter Witham Peter Witham

      Hi Fabrice,

      I would suggest first checking that you have everything in place and did not miss a step, if that does not help then I would suggest giving me as many details as you can. Without knowing where it is not working, or anything that might be appearing in the debugger it is hard for me to make a guess as to what the problem is.

      Regards,
      Peter.

      • Fabrice
        Author
        Fabrice Fabrice

        Thank you for this return, in fact I tried, because I start, to make a list of favorites. For example I have different views with on each views a button to send a label and an image to a tableview which is my list of favorites and from this view can return to the original view. Frankly I have looked for examples on the internet to help me but I have not found anything and I am charging for help. Here is an example of what I did today, only the passage of a text box, which adds the line well from the views but one clears the other at the time of sending. And frankly I can not go further.

        • Peter Witham
          Author
          Peter Witham Peter Witham

          Have you tried comparing my sample code download in the article and comparing that with what you have? I feel you are probably missing a connection somewhere in either of the controllers.

          • Fabrice
            Author
            Fabrice Fabrice

            Yes I did like you and adding the passage of an image and between two view controller it works. I tried doing the same thing from different viewcontroller to a tableview. When the data arrive from the different view in the table they are replaced and do not remain in the table after closing.

          • Peter Witham
            Author
            Peter Witham Peter Witham

            I’m not sure I fully understand, what do you mean by “view in the table they are replaced and do not remain in the table after closing.”?

            Closing the app, the view?

          • Fabrice
            Author
            Fabrice Fabrice

            Sorry for my English. I will try to be clearer. I have a view with a label and a photo. On this view I have a button add to favorites. When I click on the button the label and the image are sent to a table that is my favorites list. I have a second view with the same elements. When I click on the button the image and the label of this second view are sent in the list of favorites. But replaces the information that was sent from the first view. Then when I close the application and I open it again the information that was in the favorites list is deleted, it keeps nothing in the list. I tried very well I can not solve these problems and create a list of favorites worthy of the name 🙂

          • Peter Witham
            Author
            Peter Witham Peter Witham

            No problem on the English, I understand it just fine.

            It sounds more like a data persistence problem than that of sending data to a view. A couple of things to note,

            1. Once a view is removed then the data sent to it will no longer be valid and therefore not display again.

            2. Have you considered storing the data so that when the app comes back or starts up it can continue from where you left off? I have a tutorial using the NSUserDefaults to save and load data that might help for that.

            https://peterwitham.com/swift/how-to-save-and-load-your-ios-application-settings-using-userdefaults/

          • Fabrice
            Author
            Fabrice Fabrice

            Thank you how can I make you pass an example so that it is more speaking ??

          • Peter Witham
            Author
            Peter Witham Peter Witham

            I included a link in the previous comment on storing data using NSUserDefaults. You can also use the search bar on my site (top right) and search for NSUserDefaults to see the example.