4

I am learning iOS and I have written a simple iPhone app using iOS 5. The app shows a UITableView populated with Speakers' names, when I select one of the names its supposed to go to a UIViewController and show details about that person (name, address, etc), so its really two ViewControllers a UITableViewController and UIViewController (both subclassed).

So, in MICSpeakersTableViewController : UITableViewController I have this:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    MICSpeakerDetailViewController *detailViewController = [[MICSpeakerDetailViewController alloc] initWithNibName:@"Detail" bundle:nil];    

    [detailViewController setSpeaker:[[self getSpeakers] objectAtIndex:indexPath.row]];
    [self.navigationController pushViewController:detailViewController animated:YES];    
}

which gets called when I select it and populates the speaker (in that its not nil and description matches).

Then I have this in the same implementation:

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    NSIndexPath *indexPath = [ self.tableView indexPathForCell:sender];

    if ([segue.identifier isEqualToString:@"Detail"])
        [segue.destinationViewController setSpeaker:[[self getSpeakers] objectAtIndex:indexPath.row]];
}

Which also gets called and the segue.identifier is Detail and the destinationViewController's speaker is set correctly (is not nil, description matches). I am not quite sure why I have to set that again since I am setting it in didSelectRowAtIndexPath but I set it again and it seems harmless.

Finally, in the MICSpeakerDetailViewController, the initWithNibName method is called and the self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; returns an instance.

However, the segue never happens and viewDidLoad is never called.

Its probably something small but I can't figure it out... any advice?

Edit: Here is a screenshot of the storyboard showing the segue and the controllers:

enter image description here

jrturton
  • 118,105
  • 32
  • 252
  • 268
knaak
  • 1,293
  • 1
  • 12
  • 18
  • 1
    If you've got a push segue defined from your cell to the detail controller, you dont need all that stuff in the didSelectRow... Method. Do you have such a segue? – jrturton Feb 23 '12 at 15:30
  • @jrturton Yes, from my story board I have a "push segue from speakerCell to Speaker Detail View Controller" speakerCell is my identifier for UITableViewCell (the prototype of my dynamic table) and Speaker Detail View Controller is the View Controller I have subclassed. I added the identifier to the segue called Detail for my prepare to Segue. – knaak Feb 23 '12 at 15:44
  • Are both your view controllers embedded in a navigation controller in the storyboard? – jrturton Feb 23 '12 at 15:46
  • @jrturton No. The UITableViewController has a root relationship and is embedded in a wrapping UITabBarController. The UITableViewController has a push segue to the UIViewController (which is not working). I tried deleting the wrapping UITabBarViewController but it had the same behaviour. – knaak Feb 23 '12 at 16:47

1 Answers1

6

You have to embed the view controllers in a navigation controller for push segues to work. I don't know why it lets you define them without this in place.

To do this, click on your table view controller, then choose Editor --> Embed In --> Navigation Controller. If you should also be within a tab bar controller, then the navigation controller is embedded in that in a similar fashion. You should see the following:

enter image description here

Your segue will now work.

jrturton
  • 118,105
  • 32
  • 252
  • 268
  • THANK YOU. I thought that a tab bar controller WAS a type of navigation controller and therefore I didn't need to embedded my UITableViewController into one. Since everything seemed to work except the segue, I concentrated myself on that. Thanks again! – knaak Feb 23 '12 at 21:04
  • Thanks for saving me a bunch of time. – Arunabh Das Aug 13 '12 at 21:41