Reputation: 618
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:
I call:
[self performSegueWithIdentifier:@"programToSessions" sender:self];
prepareForSegue gets called, but nothing afterwards. No error, no warning. The new UITableViewController doesn't show up.
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];
}
Upvotes: 4
Views: 8527
Reputation: 2193
You don't have to performSegue
programmatically.
You could create a segue from the first UITableViewController to the second on the storyboard, by control dragging from the UITableViewCell of the first UITableViewController to the second UITableViewController. If the segue is not performed, its most likely reason is that, cell identifier in the method
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
and in the "Attributes Inspector" do not match.
To pass data from the the first UITableViewController to the second add the following method to the first:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"loadMyDetailView"]) {
MyDetailViewController *detailVC = [segue destinationViewController];
NSIndexPath *selectedRowIndex = [self.tableView indexPathForSelectedRow];
detailVC.dataToPass = [self getDataToPass:selectedRowIndex.row];
}
}
Upvotes: 1
Reputation: 80271
You have to use prepareForSegue:sender:
to fire the equivalent of didSelectRowAtIndexPath:
. (Empty out the latter.) Instead of pushing the new view controller on the navigation stack, the segue already has a property destinationViewController
that will just work automatically. You can modify this property if you want to customize the new view controller. Make sure segue.identifier
is 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:
TabBarController --(relationship)--> NavigationController
--(relationship)--> ViewController
--(segue)--> next ViewController
Make sure all these are correct in storyboard and see if it works.
Upvotes: 3