在Apples MultipleDetailViews示例中加载已初始化的DetailViewControllers

苹果在他们的iOS开发网站上提供了一个关于如何使用不同细节视图的分割视图的例子( 参见MultipleDetailViews示例 )。 在RootViewController中,单元格被选中,一个新的DetailViewController被初始化:

- (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]; } 

现在我的想法是不是每次初始化viewcontrollers,只是初始化viewDidLoad(也标题)中的控制器,并在单元格被选中时传递它们的引用:

在rootviewcontroller中的部分viewDidLoad:

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

现在tableView didSelectrow方法看起来像这样:

 - (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]; } 

在横向模式下,一切正常,但在纵向模式下,从第一个视图控制器切换到第二个,然后切换到第一个,然后切换到第二个。 发生以下消息:由于未捕获的exception“NSInvalidArgumentException”而终止应用程序,原因:“不能从不具有窗口的视图呈现popup窗口。

从昨天晚上开始,我试图弄清楚这一点,但是我没有find解决办法。 有人有个想法吗?

干杯,多米尼克

我有一个类似的问题,但我发现这个post ,展示了这个想法,你必须在设置splitView的视图控制器之前从以前的detailView中删除leftBarButtonItem。 这段代码解决了我的问题。

这是由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; 

}