How to update DetailView using MasterDetail Application Template

5StringRyan picture 5StringRyan · Oct 28, 2011 · Viewed 13.9k times · Source

I'm new to using the split view for creating iPad applications. When I first create the project just using the standard MasterDetail Application template (Xcode 4.2), it creates a MasterViewController and a DetailViewController. The template has the following method that is called when a row is selected from the popover table (master detail view controller):

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

if (!self.detailViewController) 
{
    self.detailViewController = [[DetailViewController alloc]        initWithNibName:@"DetailViewController" bundle:nil]; 
}
[self.navigationController pushViewController:self.detailViewController animated:YES];

Now I understand when you are using a regular navigation controller if you are programing for an iPhone you just do this type of thing to push on another view controller on to the stack. However, with this template, it just pushes the detail view onto the popover rather than updating what is already present. I'm confused as what I need to update to select something from the pop over (master detail view), and then have the detailView update.

Update:

To try and test out the "detailItem" that is already setup for you in the DetailViewController, I commented out the pushViewController and added the following:

//[self.navigationController pushViewController:self.detailViewController animated:YES];
self.detailViewController.detailItem = @"Test";

// setter in detailViewController
- (void)setDetailItem:(id)newDetailItem
{
    if (_detailItem != newDetailItem) {
        _detailItem = newDetailItem;

        // Update the view.
        [self configureView];
    }

    if (self.masterPopoverController != nil) {
        [self.masterPopoverController dismissPopoverAnimated:YES];
    }        
}

- (void)configureView
{
    // Update the user interface for the detail item.
    // detailDescriptionLabel.text is a IBOutlet to the label on the detailView
    if (self.detailItem) {
        self.detailDescriptionLabel.text = [self.detailItem description];
    }
}

According to this code, the text of the label on the detailViewController should be updated. However, when I do click on the item in the master view controller table, nothing happens.

Answer

Kevin picture Kevin · Oct 28, 2011

There are a couple different ways you could do it. First off, like you said, remove the pushViewController call (I don't know why Apple's template does this... maybe just to show you you can?).

Next, let your MasterViewController know about the DetailViewController that is already displayed. I usually set master.detailViewController = detailViewController in the appDelegate.

Remember, the DetailViewController is already being displayed, so you won't always need to realloc it (unless you are replacing it with some other view)

First Option

Use delegate calls to set the information. Declare a protocol to pass information to the detailView and have it display it appropriately. Here is a tutorial describing this in more detail.

Second Option

Pass DetailViewController some data & override the setter to refresh the detailView. Here is a tutorial describing this in more detail.

// in DetailViewController    
- (void)setDetailItem:(id)newDetailItem {
        if (detailItem != newDetailItem) {
            [detailItem release];
            detailItem = [newDetailItem retain];

            // Update the view.
            navigationBar.topItem.title = detailItem;
        NSString * imageName = [NSString stringWithFormat:@"%@.png",detailItem];
        [self.fruitImageView setImage:[UIImage imageNamed:imageName]];
        }
    }

Edit: Just looked at the template again, and setDetailItem type code is already in there, but the code is creating a completely new detailView so the detailView that is viewable on the splitViewController is not changed at all.