7

I am using Storyboard in my app and I want to pass data from one view to another view.

Instead of using segues I am using instantiateViewControllerWithIdentifier. In this case I am instantiate from my first TableViewController to a NavigationController which has a second TableViewController attached because I need the navigation in the second TableViewController. Now I want to pass data from my first TableviewController, depending which row was clicked, to my second TableviewController. In this case newTopViewController would be my NavigationController but my problem is now how to pass data from firstTableViewController to the secondTableviewController.

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        NSString *identifier = [NSString stringWithFormat:@"%@Top", [menuArray objectAtIndex:indexPath.row]];


        UIViewController *newTopViewController = [self.storyboard instantiateViewControllerWithIdentifier:identifier];




    }

enter image description here

halloway4b
  • 573
  • 1
  • 11
  • 23
  • possible duplicate of [Passing Data between View Controllers](http://stackoverflow.com/questions/5210535/passing-data-between-view-controllers) – Carl Veazey Apr 05 '13 at 12:09
  • I don't see a solution in this post. I am using instantiate controller because I don't use segues. So can I still use prepareforsegue is there is no segue? – halloway4b Apr 05 '13 at 12:22
  • Where a view controller is instantiated shouldn't change how you pass messages to it. – Carl Veazey Apr 05 '13 at 17:17
  • How can I pass data if the controller which is instantiated is a Navigation Controller? – halloway4b Apr 06 '13 at 20:41
  • It sounds like you're asking something like "I'm loading a `UINavigationController` from a Storyboard using `instantiateViewControllerWithIdentifier:`. Inside the navigation controller is a table view controller. Keeping in mind I'm not using a segue, how do I pass data to the table view controller, and show the navigation controller?" Is that right? – Carl Veazey Apr 06 '13 at 21:19
  • That is right. Because if I am presenting the table view controller directly I dont have the navigation bar. I will add a screenshot. – halloway4b Apr 07 '13 at 07:25
  • So I will pass data from menu view controller to sample table view controller but instantiate the navigation controller because otherwise I wouldn't have the Navigation bar. – halloway4b Apr 07 '13 at 07:31

4 Answers4

17

If you instantiate a navigationController, you can use the viewControllers property to get the inner viewController of the navigation controller.

Something like this:

UINavigationController *navigationController = [self.storyboard instantiateViewControllerWithIdentifier:identifier];
MBFancyViewController *viewController = navigationController.viewControllers[0];

// setup "inner" view controller
viewController.foo = bar;

[self presentViewController:navigationController animated:YES completion:nil];
Matthias Bauch
  • 89,811
  • 20
  • 225
  • 247
  • You nailed it. Many thanks. With this hint I found out that UINavigationController has a property called topViewController. Many thanks. Works like a charm with both ways. I have edited your answer with the other way. – halloway4b Apr 07 '13 at 13:07
5
newTopViewController.anyVariableToShow= anyVariableToSend;

I do this pretty often on a few of my apps...

//Create new VC

CookViewController *detailViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"CookVC"];

//Set recipe
[detailViewController setRecipe:recipe];

//Pop over VC (can be pushed with a nav controller)
[self  presentPopupViewController:detailViewController animationType:MJPopupViewAnimationFade];

If you aren't using a navigation controller or segues, then I think you need to reconsider your app design.

William Falcon
  • 9,813
  • 14
  • 67
  • 110
  • newTopViewController is a NavigationController but I want to pass the data to my secondTableViewController. – halloway4b Apr 05 '13 at 12:20
  • If I say newTopViewController.title = @"Whatever"; the title doesn't change because the secondTableviewController is displayed with a Navigationbar. If I would instantiate the secondTableViewController directly I can pass the data like secondTableViewController.title = @"Whatever" but I don't have a Navigationbar in my tableview. – halloway4b Apr 05 '13 at 12:57
0

Actually it's not just a data pass problem as this is a program control and data transfer question together. Even you would have to rethink about your app's concept, as you'd like to use storyboard without the meaning of storyboard, it's up to you and I hope you have good reason to do what you do.

So when you decided not to use segue you lost the new and comfortable way of instantiating a new controller and transferring data with it and you have to do the transfer of control and the data in two distinct steps. When you instantiate another scene in storyboard (like you do with instantiateViewControllerWithIdentifier:) you just instantiated a new controller and transferred the control but not the data. Just think about it as you instantiated a new controller from a xib in an old way (so you have to use initWithCoder: or awakeFromNib in the second view controller as the storyboard will not call initWithName:bundle:), but did not do anything more.

So you will have a new controller (it named in the identity part of the second storyboard) which is hanging in the universe without any relationship or connection with anything else (as the storyboard picture illustrates it nicely) and you could do with it what you'd like.

So you'd like to do something and you need data from the previous storyboard (ViewController). What you need is making available those data to the second storyboard(ViewController), and as you know there are lot of solution for this which were available long time before even storyboard is existed.

So regarding your code, the "data transfer" is depending on your design, whether the two controllers are subclasses of each other or whatsoever...

If you don't like to deal with subclassing and like to decoupling them as much as possible, the best way just make a property of your data in the first controller and refer to them from the second (after importing the first's .h file) and just refer to it in it's viewDidLoad or in initWithCoder: or anywhere where you need them, as

secondViewControllerdata = firstViewControllerdata.thatDataProperty

Of course you can do the same in reverse and make a property of the second controller and refer to it in your first view controller.

BootMaker
  • 1,639
  • 1
  • 22
  • 24
0

You can define some parameter in UIViewController to receive data:

@property (assign) int param1;

@property (retain) NSMutableArray *param2;

and use below to pass the data:

[newTopViewController setParam1:XX];

[newTopViewController setParam2:XX];

Community
  • 1
  • 1
Kaya Zhou
  • 13
  • 5