iOS Programming Recipe 5: Passing Values Between Segues with PrepareForSegue

In Part 1 and 2 of Recipe 3 I stepped through creating a modal relationship using storyboards. There was no code needed to make this relationship using storyboards. If you want to pass information from the presenting view to the presented view you’ll need to add some code.

Assumptions

  • You know how to set up a segue relationship using the storyboard. If not go read part 1 and 2 of Recipe 3 here: Part 1Part 2

Setting Up the Views

To start off, I created a new single view controller project and replaced the view controller with a navigation view controller. Then I deleted the root controller and added two new view controllers. I made one view controller the root view controller, and I didn’t setup the segue on the other controller for now. Then I gave each views the titles “Root View Controller” and “First View Controller” respectively. See recipe 3 for more details on setting this up.

Next I deleted the viewController class and all of it’s refferences. Delete the viewController.m file and viewController.h file and Xcode will ask you if you would like to remove the refferences.

Next we’ll need to create two new UIViewController Classes. To do this push the plus sign in the bottom left hand corner of the project navigator.

Create New UIViewController Classes

When prompted choose objective-C class under Cocoa Touch and press next. For the next prompt name the Class “RootViewController” and choose the subclass “UIViewController” then press next. You will then press create on the next prompt. Repeat this step and name the next class “FirstViewController”.

Choosing UIViewController subclass

When you’re done creating classes you should see the newly created .m and .h files in the project navigator.

New Project Navigator

 

The last thing we’ll want to do is connect our new classes to our views on the storyboard. To do this, select the view and in the utilities pane under the identity inspector choose the class from the dropdown.  Do this for both the RootViewController and the FirstViewController.

Choose View Controller Class

Now we’re ready to add some content to our views.

Adding Content to the Views

We’ll want to pass something simple from one view to the next. I can’t think of anything more simple then text, so we’ll send contact information to the new view when a button is pushed. We’ll have two buttons: One button for John and one for Joe.

From the Objects library in the Utility Pane drag two buttons onto the RootViewController. Title one Joe and the other one John. I also added a label at the top with the text “Who Do You Wanna Know?”

On the other view contoller add six text labels from the objects library and title them as show in the image below.

Adding Labels

Now We’ll Go ahead and create the push segues from both the buttons by control clicking on each button and dragging over to the First View Controller. When you’re done your storyboard should look like the following image:

Final View

Now we’re ready to make some connections.

Making the Connections

The First thing we’ll want to do is giver our segues identifiers.

Open up the documents outline by pushing the play button in the bottom left hand corner of the storyboard. You will now see the Document Outline open up.

There you will see under the Root View Controller the two Segues you have created. Select the one that says “Push Segue from John to First View Controller” and change the identiefier to johnSegue from the attributes inspector from the utilities pane. Do the same for the Segue to joe except with the identifier “joeSegue”.

View of Document Outline

 

Setting the Identifier

Now we’ll want to create outlets in the destination view controller for the “First View Controller”.

Here I created three outlets titled “fname”,”phone”, and “bday”.

I also created three text NSString properties titled “fnameText”,”phoneText”,and “bdayText”.

Your FirstViewController.h file should now look something like this:


#import <UIKit/UIKit.h>

@interface FirstViewController : UIViewController
@property (strong, nonatomic) IBOutlet UILabel *fname;
@property (strong, nonatomic) IBOutlet UILabel *phone;
@property (strong, nonatomic) IBOutlet UILabel *bday;
@property (strong, nonatomic)          NSString *fnameText;
@property (strong, nonatomic)          NSString *phoneText;
@property (strong, nonatomic)          NSString *bdayText;

@end

Now we’re ready to prepare for our segue.

Preparing for the Segue

In order to pass information from one view controller to another using the UIStoryboardSegue object we’ll need to take advantage of the current view controller’s prepareForSegue:sender: method.

In the RootViewController.m file add the prepareForSegue:sender: method as show in the code below.


-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{

NSLog(@"prepareForSegue: %@", segue.identifier);
if([segue.identifier isEqualToString:@"joeSegue"])
{

}else if([segue.identifier isEqualToString:@"johnSegue"]){

}

}

You’ll also notice that there is a couple of extra pieces added inside the method. First were using NSLog to print out the segue identifier to the debugging window, and second there is an if else conditional to check and see which segue is being called.

Now we’ll create an intance of the FirstViewController class inside our prepareforsegue method so we can set some values.


-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{

    FirstViewController *transferViewController = segue.destinationViewController;

    NSLog(@"prepareForSegue: %@", segue.identifier);
    if([segue.identifier isEqualToString:@"joeSegue"])
    {

    }else if([segue.identifier isEqualToString:@"joeSegue"]){

    }

}

In this code I have created an instance of our class FirstViewController and set it to our segue destination view controller. Now we have the ability to set properties inside the FirstViewController class.

So now you’re probably thinking we can just call one of our label properties inside the FirstViewController class and set the values directly EX. transferViewController.fname.text = @”Joe Hoffman”. While this sounds like a good idea it won’t work. This has to do with the order in which the prepareforsegue method is called and when the view loads. These types of issues are one reason many developers preffer not to use storyboarding.

To get around this issue we’ll set some NSString properties of the First View Controller like so:


-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{

    FirstViewController *transferViewController = segue.destinationViewController;

    NSLog(@"prepareForSegue: %@", segue.identifier);
    if([segue.identifier isEqualToString:@"joeSegue"])
    {

        transferViewController.fnameText = @"Joe Hoffman";
        transferViewController.phoneText = @"555-555-5556";
        transferViewController.bdayText = @"06/27/1984";

    }else if([segue.identifier isEqualToString:@"johnSegue"]){

        transferViewController.fnameText = @"John Smith";
        transferViewController.phoneText = @"555-555-5556";
        transferViewController.bdayText = @"06/27/1972";
    }

}

Now there’s one more thing to do. In the FirstViewController.m file, modify the ViewDidLoad method to incorporate the following changes:


- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.fname.text = self.fnameText;
    self.phone.text = self.phoneText;
    self.bday.text = self.bdayText;
}

Here we are setting the label text to the NSStrings we assigned in our prepareForSegue method. Now when you build and load you should see the correct data being transfered to the the First View Controller. Don’t forget to import the the first view controller’s header file into the rootViewController. Here’s what I have after pushing the “John” button:

Finished App

That’s all there is too it! On a larger scale we would probably want to parametize our contacts and use a UITableView to display them. Soon we’ll have a recipe that covers the UITableView.

About Joe Hoffman

I am An Electrical Engineer that spends a lot of my off time doing web development and other programming. Currently I am trying to expand my knowledge with iOS and I find that writing tutorials helps me learn more thoroughly as well as provide some useful info to others.

Comments

  1. SUCH a pain to be able to set up so much of my project in Storyboard, only to be shut down at the last minute by little things like this.

    Ah well. Thanks for posting this!

    • You’re Welcome Juan,

      I love the idea of storyboards and for simple stuff they work well, but as a beginning developer they can sure add a ton of confusion. It would be nice if the storyboard could somehow create the same code in your project that you would have to create without the use of storyboards. That way, with or without the visual aid, the code would be the same. Maybe someday.

      -Joe

  2. Michael Schinis says:

    Hello,

    I seem to have found a small problem on your guide. It seems you need to import the FirstViewController.h at the top of RootViewController in order to use:

    FirstViewController *transferViewController = segue.destinationViewController;

    later on in prepareForSegue.

    Currently using: xCode 5 DP4.

    Michael

  3. Great work Man. Helped a lot . Thanks

  4. In the “First View Controller” screen, there is a default button (called “Root View Controller”) to go back to the previous screen. This button is not shown in the UI tool. Can you share on how to create a unwind segue to send back some data (if any) from the second screen to the first screen? I am able to do it with the UI tool, by control drag a visible button (ex. add Done button to second screen) from the navigation bar to the unwind segue’s destination proxy object (green Exit icon). But with push segue from the first screen, there is no visible button to drag from. Also with the default back button, how do we know what is the name of segue action method we have to implement to handle the unwind segue?

    • Joe Hoffman says:

      Hi Noomy,

      I’m having trouble figuring out what you are asking for. For your second question, You can give give your segue an identifier by clicking the line that goes between controllers and then editing creating and identifier from the attributes inspector.

  5. This is a great tutorial. Thanks for posting. I have a main menu with 2 buttons that I want to segue into two unique versions of the same calculator view. I am not trying to pass any data between the controllers. I just want to have two separate versions of the calculator/timer view running at the same time. Can you advise how I would set up that up? I have created separate segues from the two buttons in the menu going to the calculator view, and have given them unique identifiers. That’s as far as I have gotten. Of course the calculator is totally coded. This is one of the last things I need to sort out before finishing this app and I am at a brick wall. Your help would be greatly appreciated. Thanks!!!

  6. Hi, thanks for posting. This is very useful !! 🙂

  7. “While this sounds like a good idea it won’t work. This has to do with the order in which the prepareforsegue method is called and when the view loads.”

    This helped me so much! I was stumped why I couldn’t just set the text field directly.

  8. I have been stumped on trying to figure out how to send data to another view controller. I read countless blogs and websites and tried many different things but couldn’t get anything to work. I am so glad I stumbled onto your blog! I am very new at obj-c and xcode (java coder), so I thank you so much!! this has helped me out with my project!

    thank you!!

    • Joe Hoffman says:

      No Problem Sam!

      You may also want to learn how to create custom initializers, that way you can set the data you need when a class is created.

  9. vidnyan says:

    Hello joe,I used the same code as u have shown.
    But M not able to get the details on FirstViewController. I am using Xcode5.
    I am very new to iOS development.

  10. Mohamed Omar says:

    This topic is very helpful for me. Im new at objective-c and I searched a lot to know how to pass data through navigation and the topic is simple and very easy to understand.
    Thank you very much.

  11. I found something great in this tutorial if you want to pass data from two view controller
    http://wallstreetdeveloper.com/passing-data-view-controllers/

  12. I don’t see how you actually passed any values in this example. You had a RootViewController and when you clicked on a button it executed the segue method of FirstViewController which created some values and displayed them on the screen. Kudos if you are able to even get the segue even to fire. I have confirmed that my segue is not executing even though the second page is loading. None of the data populates or displays but I really need an example of how to get data from one view to be passed to another. I have seen 4 examples that don’t actually work and now this one that doesn’t actually pass data.

    • Joe Hoffman says:

      I don’t understand why this would occur, if using storyboards and a segue is properly created then

      - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

      should always happen.I would check and make sure you created the segue properly.

  13. I got a bit crazy because it wasn’t working, finally i discover that i used Capital letters for the id of the segue, while the code is written without it :(.

    Finally it work.

Speak Your Mind

*

css.php
Privacy Policy