Passing data between view controllers


I’m a newbie and a little frustrated. I am trying to pass data between the UITabBarController and failing hardly at it.

If anyone can help me, I will be grateful. I have a UITabBarController added to the AppDelegate views but I have no idea on how to pass data around. For example, my intuition tells me that I have to define a variable in “the root” which has connection to the tab bar controller so I guess that is the main app delegate. But, tbh, I don’t even know where to define this variable in the app delegate. Is it inside the @interface? anywhere after it? before @end? And I tried initializing a NSString variable there and put the main app delegate.h in the other view controller but they cannot recognize the variable.

I should explain that it is slightly complicated because I am incorporating a 3rd party SDK (red laser) into my app and they have a wrapper view controller (overlay) which calls their SDK and they provide a function which returns the barcode after scanning. I am able to “collect” this barcode but I don’t know how to pass it to other views/view controllers.

@the author: Kindly reminder! You mentioned in the book (page 180) that many programmers new to iphone programming struggle with passing data and yet you only have 1 example (up to that point unless I missed any, please tell!) in which a UITableViewController passes data to another controller (ItemDetail…). If it is something many programmers struggle with, it will be nice to add a little bit more example and clarification on how to do just that. In fact, I don’t really understand that particular code sample.


Being a newbie is frustrating - and it will be frustrating for a long time to come. There are no shortcuts to learning this stuff.

There are many ways to do what you want to do. I’m going to give you the simplest way. In time, you will learn more robust and difficult ways, but for now, this will work.

If you have view controllers in tab bar controller, and would like them to be able to pass data back and forth, you will have to give the view controllers instance variables that point to the other view controllers.

For example, if you had a MyFirstViewController and MySecondViewController in a UITabBarController, you would add a MySecondViewController instance variable to MyFirstViewController and expose it as a property:

#import <UIKit/UIKit.h>
#import "MySecondViewController.h"

@interface MyFirstViewController : UIViewController
     MySecondViewController *otherViewController;
@property (nonatomic, assign) MySecondViewController *otherViewController;

Then, when you create your view controllers, you would link them up. This most likely happens in the App Delegate.

- (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)optionsDict
    MyFirstViewController *firstVC = [[MyFirstViewController alloc] init];
    MySecondViewController *secondVC = [[MySecondViewController alloc] init];
   [firstVC setOtherViewController];
   NSArray *vcs = [NSArray arrayWithObjects:firstVC, secondVC, nil];   

   UITabBarController *tbc = [[UITabBarController alloc] init];
   [tbc setViewControllers:vcs];
   [window setRootViewController:tbc];
    [window makeKeyAndVisible];
    return YES;

MySecondViewController will implement methods that allow it to receive messages that have whatever data you want to pass as arguments, and MyFirstViewController will send these messages to its otherViewController instance variable.


So awesome!

Thanks Joe!


Hey Joe,

A question:
I tried the solution you mentioned here and it builds but ultimately crashes due to exception ‘NSInvalidArguementException’ reason
1stViewController setOtherViewController:]: unrecognized selector sent to instance …

Is the setOtherViewController the method in which I have to implement? You mentioned to pass the data as the arguement so at the minimum, it has to be in this format:

[vc1 methodToPassData:vc2 Data:data]



Yes, you would have to synthesize that property to implement the method setOtherViewController.

Your passing data method doesn’t need to take VC2 as an argument, you simply send the message to VC2 with the data as an argument. Of course, you will have to determine what that method looks like as it is specific to the task you are trying to accomplish.