How to update DetailView using MasterDetail Application Template
Asked Answered
K

1

11

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.

Koniology answered 28/10, 2011 at 16:7 Comment(0)
P
8

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.

Psychology answered 28/10, 2011 at 19:10 Comment(6)
What do you mean creating another detailView as opposed to the "real" detailView?Koniology
Sorry for being ambiguous. By "real" I meant the one defined in the AppDelegate and added to the SplitViewController (So, the one actually viewable on the right-hand side on landscape and full screen on portrait). In the template, they are creating a completely new one and adding it to the navigation controller.Psychology
Just curious, any reason why this new detail page is being created? I mean if this "new" detailViewController object is being created, changed but not pushed on the stack, what purpose does it have? At this point I've created a "DetailViewController" property in the AppDelegate class, and have just been accessing the AppDelegate.detailViewController property to update. I'm wondering if this is the way to go...Koniology
At that point, it really has none. The only reason I can think that Apple included it was to show you that you could push views onto the UIPopOver navigation stack. Your solution is fine, I like the slightly cleaner code by having a reference to the detailView in the root (master?) view but the idea is the same. If it works for you stick with it.Psychology
I'm not sure what you mean about having the reference to the detailView in the Root (Master). Provide a property that references the detailViewController object in the MasterViewController class?Koniology
Yup, exactly. By reference, I meant "pointer reference" but same difference. The MasterViewController in the template already has DetailViewController property, it just isn't set to anything until [didSelect:] action. I just make sure it is public and then set it equal to the detailView in the AppDelegate. masterViewController.detailViewController = detailViewControllerPsychology

© 2022 - 2024 — McMap. All rights reserved.