0

I have two table view controllers, one containing all the US states, the other presenting a list of data for the selected state. I have set up a segue in my main storyboard from the view controller (not the cell), and given it an identifier. For reasons beyond the scope of this post, I need to programmatically perform the segue without using the prepareForSegue method.

The source table view controller (AllStatesTableViewController) needs to execute the segue in the didSelectRowAtIndexPath method of the tableview.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    stateID = [statesDict objectForKey:cell.textLabel.text];

    DetailTableViewController *destination = [[DetailTableViewController alloc] init];

    stateGauges = [[GaugeList alloc] initWithStateIdentifier:stateID andType:nil];
    // at this point stateGauges is NOT nil

    [destination setStateGauges:stateGauges];

    [self performSegueWithIdentifier:@"sgShowStateDetail" sender:self];
}

The segue performs as intended in that it navigates to its destination, but stateGauges is nil in the destination table view controller. It is not nil in the source table view controller. stateGuages is declared as a property in DetailTableViewController. Obviously I am doing something wrong. Any suggestions?

Thanks! V

2 Answers2

4

On your storyboard you need to choose to push your segue from your cell.

enter image description here enter image description here

and use your prepareForSegue to pass data :

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{
    if ([segue.identifier isEqualToString:@"showDetail"]) 
    {
        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
        DetailTableViewController *detailTableViewController = segue.destinationViewController;

        // Pass data here
        destViewController.stateGauges = stateGauges;
    }
}

Have a look here for more information

Jordan Montel
  • 8,227
  • 2
  • 35
  • 40
  • Pushing from the cell creates issues with the navigation controller when executing segues programmatically. It results in the following: nested push animation can result in corrupted navigation bar. See [this post](http://stackoverflow.com/questions/5525519/iphone-uinavigation-issue-nested-push-animation-can-result-in-corrupted-naviga) –  Oct 14 '13 at 16:12
  • you can embedded a navigation controller in your view in the prepareForSegue – Jordan Montel Oct 14 '13 at 16:15
  • Unfortunately, using prepareForSegue is causing weird issues with a network activity indicator. It's been suggested to us NOT to use prepareForSegue for this reason –  Oct 14 '13 at 16:23
  • You don't specify this in your question :) But, I don't like Storyboard... use XIB ahah :) – Jordan Montel Oct 14 '13 at 16:27
  • ok so I had a quick look sorry. What is the declaration of your property `stateGauges` in your detail view ? And where do you initialize this property ? – Jordan Montel Oct 14 '13 at 17:03
  • In the header of my DetailTableViewController I have decalred stateGuages as a property using the following @property (nonatomic,strong) GaugeList *stateGauges; and synthesized it in the implemetation. Then I am trying to create an instance of the DetailTableViewController and calling setStateGauges and passing in the stateGauges object from the source table view controller –  Oct 14 '13 at 17:22
  • I don't understand why you use `didSelectRowAtIndexPath` with storyboard ? I tried the tutorial (never try storyboard before) and it's work perfectly to pass data. – Jordan Montel Oct 14 '13 at 19:23
1

I ran into this before too. I found that when I let the storyboard handle the segue, it instantiates a new view controller. This is why stateGauges is nil, because you set stateGauges in your programmatically created view controller, not the one the storyboard created. If you won't use prepareForSeque, remove the segue from your AllStatesViewController to your DetailTableViewController in your storyboard. Then programmatically instantiate the storyboard, the view controller, setGauges, then present your view controller. Also, make sure you put "ShowStateDetail" in the "Storyboard ID" field, in the Identity section, on that DetailTableViewController in your storyboard.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    stateID = [statesDict objectForKey:cell.textLabel.text];

    DetailTableViewController *destination = [[UIStoryboard storyboardWithName:@"yourStoryBoardName" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:@"ShowStateDetail"];

    stateGauges = [[GaugeList alloc] initWithStateIdentifier:stateID andType:nil];

    [destination setStateGauges:stateGauges];

    [self presentViewController:destination animated:YES completion:nil];
}
Wyatt Page
  • 309
  • 2
  • 10