Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

Siver Salih
Siver Salih
2,795 Points

How to Pass Data between two View Controllers when you have Tab Bar and Navigation Controller in between

Hi, I found myself in little complicated situation where I've a storyboard layout as such I have MainViewController -> Tab Bar Controller (5 items) -> Navigation Controller (1 for each item) -> Table View Controller (1 for each NC) -> Web View Controller (1 for each Table)

alt text

What I am trying to achieve and need your help to guide me in this process is when the application first launches and the user press the "Load Button" on MainViewController, I would like to load the data for all the Tab Bar items, before it transit to Tab Bar Controller and to the first Table View Controller.

Currently how I have it; when the user press the "Load Button" on MainViewController when the application first starts, it loads the first (top) view controller (Table View) on Tab Bar Controller but not the other items. When the user press the second Tab Bar item, then it load the data for that Table View Controller. Typical case, no issue.

In this case, I want to load the data in MainViewController and pass the data to corresponding Table View Controller when Tab Bar Controller gets called. I can create variable and instantiate each Table View Controller in MainViewController but how to pass that data/table to each Table View Controller?

Thanks, Siver

4 Answers

Ravi Shankar
PLUS
Ravi Shankar
Courses Plus Student 7,823 Points

Create @property for each viewcontroller and set the required values in the MainViewController.

Siver Salih
Siver Salih
2,795 Points

Hi Ravi,

Thanks for your quick response.

I've tried as you suggested and the data still doesn't get carried to when Table View Controller gets called. Here is what I have, and a proof the data doesn't get carried to Table View Controller

Let's take an example for only one Table View Controller (i.e GuardianViewController) which is the top view controller in Tab Bar Controller.

In MainViewController.h, I've created property for one Table View Controller (GuardianViewController) like this

@property (strong, nonatomic) GuardianViewController *GuardianViewController;

In GuardianViewController.h, it has three property and one method

@property (weak, nonatomic) IBOutlet UITableView *myTableView
@property (strong,nonatomic) GuardianXMLParser *GuardianXMLParser;
@property (strong, nonatomic) CustomCell *cell;
- (GuardianXMLParser *) getXMLParser;

So in MainViewController.m and in viewDidLoad method, I've initialized and set the data like this

self.GuardianViewController = [[GuardianViewController alloc] init];
self.GuardianViewController.GuardianXMLParser = [[GuardianXMLParser alloc] init];
self.GuardianViewController.GuardianXMLParser = [self.GuardianViewController getXMLParser];

In getXMLParser in the line above; this line will call GuardianViewController and GuardianViewController calls getXMLParser method to fill the data for the variable GuardianXMLParser in GuardianViewController. I don't think anything wrong with the way I'm getting the data for GuardianXMLParser.

For the other two properties in GuardianViewController, myTableView and cell. That's just to display the data when GuardianaViewController gets called. So it doesn't hold any data except what's to display once GuardianXMLParser gets loaded. Therefore I didn't initialized or set any value for these two properties.

So this is what I did and what I have, and here how I know the data doesn't get carried to Table View Controller (i.e. GuardianViewController). First subjectively, when I run launch the program it didn't display any data in the Table View. Then I thought maybe I don't have the display right (i.e myTableView or cell) and let me put NSLog in ViewDidLoad method to get one of the data (i.e. Title) for GuardianXMLParser when GuardianViewController gets called.

myBlog *blogPost = [self.GuardianXMLParser.feeds objectAtIndex:0];
NSLog(@"Title: %@",blogPost.title);

Here is the log:

2013-10-20 22:21:51.594 myBlogReader[36878:70b] Main View Controller has been Called!
2013-10-20 22:22:00.429 myBlogReader[36878:70b] Main View Controller has been Loaded!

After I press the Load Button

2013-10-20 22:22:18.952 myBlogReader[36878:70b] Tab Bar Controller has been Called!
2013-10-20 22:22:18.952 myBlogReader[36878:70b] Tab Bar Controller has been Loaded!
2013-10-20 22:22:18.955 myBlogReader[36878:70b] Navagation Controller for Guardian has been Called!
2013-10-20 22:22:18.955 myBlogReader[36878:70b] Navagation Controller for Guardian has been Loaded!
2013-10-20 22:22:18.963 myBlogReader[36878:70b] Guardian View Controller has been Called!
2013-10-20 22:22:18.963 myBlogReader[36878:70b] Title: (null)
2013-10-20 22:22:18.963 myBlogReader[36878:70b] Guardian View Controller has  been Loaded!

From display and getting the log for the variable Title, clearly the data is not getting through from Main View Controller to Table View Controller (i.e GuardianViewController) in this situation. What am I missing?

Thanks, Siver

Ravi Shankar
PLUS
Ravi Shankar
Courses Plus Student 7,823 Points

Hi Siver,

I am little confused here, I do not think the same instance "self.GuardianViewController" is available when GuardianViewController (tab) is displayed.

self.GuardianViewController = [[GuardianViewController alloc] init]; self.GuardianViewController.GuardianXMLParser = [[GuardianXMLParser alloc] init]; self.GuardianViewController.GuardianXMLParser = [self.GuardianViewController getXMLParser];

I tried to work an example for this scenario but was not successful.

Just for my understanding..

Why do you want to load all the tabs data in the MainViewController itself instead of each tab?

How/when will the data get refreshed again?

Thanks Ravi

Siver Salih
Siver Salih
2,795 Points

Hi Ravi, I also think when I've created an instance of GuardianViewController in MainViewController it is not same instance of GuardianViewController when Tab Bar Controller calls GuardianViewController to display the data/table.

However I don't think this technique about creating an instance of GuardianViewController in MainViewController is a way of passing data to GuardianViewController when it gets called. The idea I'm having when GuardianViewController gets called and instantiated by Tab Bar Controller, I want GuardianViewController load the necessary data from somewhere locally (an Object variable (i.e. GuardianXMLParser) which the data is present or visible in any files) for the Table. Your technique here I think is different. You want GuardianViewController to be ready or get instantiated before Tab Bar View Controller and when Tab Bar View Controller gets called, you just point the top view Controller to GuardianViewController which we've created in Main View Controller.

Why do I want the data get created when called in later View Controller are for two reasons:

  1. Wait Time: I rather have one long wait time than chunk of small wait time

  2. Option What to Display:Show Simplified data or Full data

The data doesn't get refreshed and only will be created once the Load Button get pressed. Otherwise its a big lag time when the data gets retrieve from the web, parse the data, and load the images periodically.

Thanks, Siver