There must be a simple solution to this, but after 4 hours of browsing StackExchange, I’m giving up and trying to get this answered here:
Situation:
iOS 5, Xcode 4.2.1, using Storyboards
Setup:
- Root Navigation Controller = UITabBarController with 5 items
- Each tab links to a UITableViewController (via segues), which works perfectly, automatically
- I have classes for each view controller and the navigation controller (UITabBarController)
- I click on a tab, say “Program”, and it shows me a list of items (in the linked UITableViewController), say one of these items is “Sessions”
- I click on “Sessions”, didSelectRowAtIndexPath gets called just fine.
- I want to perform a segue now (which I have connected from that UITableViewController, not the cell, to the new UITableViewController and given it an identifier.
-
I call:
[self performSegueWithIdentifier:@"programToSessions" sender:self]; -
prepareForSegue gets called, but nothing afterwards. No error, no warning. The new UITableViewController doesn’t show up.
- Note: It DOES show up, however, if I switch the segue to a “modal” – but it discards/hides the original tab bar at the bottom then (not intended…)
So far, my problem seemed to have a likely solution. The navigation controller. I figured, if I setup a navigation controller reference in the AppDelegate, initiated/set it once the actual root navigation controller is loaded (in viewDidLoad), i.e. basically used something along the lines of: app.navController = self.navigationController in the viewDidLoad – this could work! Right? So, I changed the segue action to:
[app.navController performSegueWithIdentifier:@"programToSessions" sender:self];
Yet, nothing changes, it does not show up.
Any ideas?
Solved:
There were a few issues here. Major issue was the fact that I missed putting a “Navigation Controller” between the UITabBarController and the UITableViewController. This can be done by adding a new “Navigation Controller” to the storyboard, then drag from UITabBarController (the rootViewController) to this new controller and set a RELATIONSHIP. Next, drag a RELATIONSHIP to the UITableViewController. So, as outlined by the correct answer it should look like:
UITabBarController –> (relationship) –> UINavigationController –> (relationship) –> UITableViewController
In order to load new UITableViewControllers on top of the last UITableViewController, a simple segue and calling it through code will suffice. The final tree will look like:
UITabBarController –> (relationship) –> UINavigationController –> (relationship) –> UITableViewController –> (segue) –> UITableViewController
Give the segue an identifier. In code, use this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:@"loadMyDetailView" sender:self];
}
You have to use
prepareForSegue:sender:to fire the equivalent ofdidSelectRowAtIndexPath:. (Empty out the latter.) Instead of pushing the new view controller on the navigation stack, the segue already has a propertydestinationViewControllerthat will just work automatically. You can modify this property if you want to customize the new view controller. Make suresegue.identifieris correct!Also, from your question I notice some confusion about the controllers of view controllers. You mention two of these: the tab bar controller and a navigation controller. In storyboard, the setup should be like this:
Make sure all these are correct in storyboard and see if it works.