Dmitry Minkovsky
Dmitry Minkovsky

Reputation: 38153

Best way to push additional UIViewControllers onto a UINavigationController

I'm working with the Master-Detail project template that comes with Xcode and referenced in http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/SecondiOSAppTutorial/

Problem: I am trying to figure out how to add additional UIViewControllers to the default UINavigationController that this template comes with.

Specifically, I would like to add a DetailEditViewController after DetailViewController. Here is what I've done to this effect so far:

In DetailViewController I added an edit button to the navigationItem:

- (void)viewDidLoad
{
    [super viewDidLoad];       
    self.navigationItem.rightBarButtonItem = 
        [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit
                                                      target:self 
                                                      action:@selector(editDetailItem:)];
    [self configureView];
}

You can see it specifies a message selector editDetailItem:, which I've implemented as:

- (void)editDetailItem:(id)sender
{
    [self.navigationController pushViewController:
        [[DetailEditViewController alloc] init] animated:YES];
}

I've created a DetailEditViewController on the Storyboard, and the code runs without crashing, producing a black, blank window with a navigation item to take me back to detail. From here on I am pretty confused:

Upvotes: 1

Views: 220

Answers (1)

rdelmar
rdelmar

Reputation: 104082

You're right, no corresponding files are produced. How is the system supposed to know what class you want? You need to create a UIViewController subclass, and change the class of the controller you drag in, to that class. The easiest way to push the new controller is to use a push segue -- if you don't have a UI element in the storyboard to connect that to, you connect it directly from the controller and give the segue an identifier (which I call "GoToEdit" in my example). In the action method for the edit button, then perform the segue:

[self performSegueWithIdentifier:@"GoToEdit" sender:self];

If you want to pass information, then you implement prepareForSegue:, something like this:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:@"GoToEdit"]) {
        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
        NSDate *object = _objects[indexPath.row];
        [[segue destinationViewController] setDetailItem:object];
    }
}

It's a good thing to check the segue identifier first. Then you can access your destinationViewController (you might have to cast it to your class, so the compiler will recognize any property of it you're trying to set), and pass what you want to it.

Upvotes: 2

Related Questions