Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems setting up a Navigation Controller using Story Board

I've set up a Navigation Controller before in previous versions of XCode but I'm using the latest version and trying to set it up using a Story Board. I have Tab Bar Controller which feeds two forms. The second form has a UITableview which I want to then move to another form when the user has made a selection using the Navigation Controller. I've set out how my relationship looks below.

enter image description here

The problem seems to be with my relationship set up. I've control clicked from the second form to the Navigation Controller and the pop up offers me a choice from 'Push, Modal or Custom'. I selected 'Push' but when I try to run the code below ir does not work.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
     NSUInteger row = [indexPath row];
     NSString *tSel = [listContents objectAtIndex:row];

     ConstantRateController *detailController = [[ConstantRateController alloc] initWithNibName:@"ConstantRateController_iPhone" bundle:nil];        
     [self.navigationController pushViewController:detailController animated:YES]
 }

I've run the code through debugger and it runs without error but the next form does not show.

like image 845
user616076 Avatar asked Apr 02 '12 16:04

user616076


1 Answers

From your description, it sounds like there are three problems:

  1. Push segues require that the source view controller be embedded in a navigation controller -- instead, you have the source view controller trying to segue to a navigation controller.

  2. The destination view controller needs to also be in the storyboard.

  3. Once you're using storyboards, you generally don't want to follow the pattern for pushing new view controllers from the pre-storyboard world (that is, creating a view controller and pushing it in tableView:didSelectRowAtIndexPath:)... doing that duplicates a bunch of the work that storyboards do for you.

Instead:

  1. Put your table view controller into a navigation controller, and the navigation controller in the tab view controller. (You can do this with the Editor > Embed In menu, or by dragging them out of the library and dragging "relationship" connections between them.)

  2. Put your destination view controller in the storyboard (if it isn't there already) by dragging out a view controller from the library and setting its class to your view controller class (ConstantRateController).

  3. Drag a push segue from the table view cell to the destination view controller:

drag to create segue

After all three steps, your storyboard should look like this:

enter image description here

Finally, in the table view controller, implement the following:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // test segue.identifier if needed
    MyViewController *viewController = segue.destinationViewController;
    NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
    // set properties of viewController based on selection indexPath
}

The segue creates and pushes the view controller; all you need to do is configure it so that its content reflects the table selection which caused the segue. (Note that if you have multiple segues from the table view controller, you should give each a unique identifier in IB and test it in prepareForSegue:sender: to configure the appropriate destination view controller.)


If you need to support multiple segues out of the table view based on which cell was picked, it's a bit different. Obviously, the storyboard can't know about cells which are populated by your delegate/dataSource, so you can't set up segues from the cell... at least, not in a dynamic table.

It sounds like you might be something like a Settings view where you have a static set of cells where each should segue to another view (like some page of settings). In that case, you might want to look at another feature you get from storyboards: static tables. If you select the table view (not the table view controller) in IB, the top of the attributes inspector lets you toggle between Dynamic Prototypes and Static Cells -- the former is what I've described above, and the latter lets you create cells and sections and edit their content entirely in IB. With static cells you can make a different segue from each... so you can make a multi-page Settings-like UI pretty much entirely in IB (of course, you'll still need code to do something when switches are flipped and whatnot).

If you need to support multiple segues out of a dynamic table, you'll need two things:

  1. A different origin for the segues -- you can't have multiple segues coming out of a cell, but you can have multiple segues coming out of the (table) view controller itself.

  2. Logic for choosing a segue based on the user's action. Here we're back to tableView:didSelectRowAtIndexPath:, but instead of creating the new view controller and pushing it on the navigation controller or presenting it modally, you just call performSegueWithIdentifier: on self.

There's a little more detail on such in this answer, and more on storyboard programming practices in general in Apple's view controllers guide:

like image 182
rickster Avatar answered Sep 20 '22 15:09

rickster