开发者

Load already initialized DetailViewControllers in Apples MultipleDetailViews Example

Apple presents on their iOS Development sites an example on how to use a splitview with different detailviews (see MultipleDetai开发者_StackOverflowlViews Example). In the RootViewController eery time the cell gets selected, a new DetailViewController is initialized:

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

/*
 Create and configure a new detail view controller appropriate for the selection.
 */
NSUInteger row = indexPath.row;

UIViewController <SubstitutableDetailViewController> *detailViewController = nil;

if (row == 0) {
    FirstDetailViewController *newDetailViewController = [[FirstDetailViewController alloc] initWithNibName:@"FirstDetailView" bundle:nil];
    detailViewController = newDetailViewController;
}

if (row == 1) {
    SecondDetailViewController *newDetailViewController = [[SecondDetailViewController alloc] initWithNibName:@"SecondDetailView" bundle:nil];
    detailViewController = newDetailViewController;
}

// Update the split view controller's view controllers array.
NSArray *viewControllers = [[NSArray alloc] initWithObjects:self.navigationController, detailViewController, nil];
splitViewController.viewControllers = viewControllers;
[viewControllers release];

// Dismiss the popover if it's present.
if (popoverController != nil) {
    [popoverController dismissPopoverAnimated:YES];
}

// Configure the new view controller's popover button (after the view has been displayed and its toolbar/navigation bar has been created).
if (rootPopoverButtonItem != nil) {
    [detailViewController showRootPopoverButtonItem:self.rootPopoverButtonItem];
}

[detailViewController release];
}

Now my idea is instead of initialising the viewcontrollers everytime, just initialize the controllers in the viewDidLoad (and also header) and pass the references of them when the cell gets selected:

part of the viewDidLoad in the rootviewcontroller:

firstDetailViewController = [[FirstDetailViewController alloc] initWithNibName:@"FirstDetailView" bundle:nil];
secondDetailViewController = [[FirstDetailViewController alloc] initWithNibName:@"FirstDetailView" bundle:nil];

Now the tableView didselectrow method looks like this:

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

/*
 Create and configure a new detail view controller appropriate for the selection.
 */
NSUInteger row = indexPath.row;

UIViewController <SubstitutableDetailViewController> *detailViewController = nil;

if (row == 0) {
    detailViewController = firstDetailViewController;
}

if (row == 1) {
    detailViewController = secondDetailViewController;
}

// Update the split view controller's view controllers array.
NSArray *viewControllers = [[NSArray alloc] initWithObjects:self.navigationController, detailViewController, nil];
splitViewController.viewControllers = viewControllers;
[viewControllers release];

// Dismiss the popover if it's present.
if (popoverController != nil) {
    [popoverController dismissPopoverAnimated:YES];
}

// Configure the new view controller's popover button (after the view has been displayed and its toolbar/navigation bar has been created).
if (rootPopoverButtonItem != nil) {
    [detailViewController showRootPopoverButtonItem:self.rootPopoverButtonItem];
}

//[detailViewController release];
}

In landscape mode everything works fine, but when in portrait mode a get an error, when switching from the firstdetailviewcontroller, to the second, then to the first and then want to switch to the second. Following message occurs: Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Popovers cannot be presented from a view which does not have a window.'

Since yesterday evening I am trying to figure this out, but i do not find a solution. Anybody an idea?

Cheers, Dominik


I had a similar issue, but I found this post that demonstrated the idea that you have to remove the leftBarButtonItem from the previous detailView before setting up the splitView's view controllers. This code fixed the issue for me.

This is the code from that written by TPoschel.

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

// Retrieve the new detail view controller
UIViewController *detailViewController = [[self.allData objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];

// Add the detail view controller to a navigation controller and set the bar style
UINavigationController *detailNavigationController = [[UINavigationController alloc] initWithRootViewController:detailViewController];
detailNavigationController.navigationBar.barStyle = [[NSUserDefaults standardUserDefaults] integerForKey:@"UIBarStyle"];

// Retrieve previous detail view controller and remove the leftBarButtonItem
UINavigationController *previousDetailNavigationController = [splitViewController.viewControllers objectAtIndex:1];
UIViewController *previousDetailViewController = [[previousDetailNavigationController viewControllers] lastObject];
previousDetailViewController.navigationItem.leftBarButtonItem = nil;

// Update the split view controller's view controllers array.
NSArray *viewControllers = [[NSArray alloc] initWithObjects:self.navigationController, detailNavigationController, nil];
splitViewController.viewControllers = viewControllers;

[detailNavigationController release];
[viewControllers release];

// Dismiss the popover if it's present.
if (popoverController != nil) {
    [popoverController dismissPopoverAnimated:YES];
}

// This sets the left bar to nil when in landscape and equal to "Menu" when in portrait.
// We need to remove rootPopoverButtonItem from the previous viewController...
detailViewController.navigationItem.leftBarButtonItem = rootPopoverButtonItem;

}

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜