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

Posted

技术标签:

【中文标题】在 Apples MultipleDetailViews 示例中加载已经初始化的 DetailViewControllers【英文标题】:Load already initialized DetailViewControllers in Apples MultipleDetailViews Example 【发布时间】:2011-06-14 06:46:18 【问题描述】:

Apple 在其 ios 开发网站上展示了一个示例,说明如何使用具有不同详细视图的拆分视图 (see MultipleDetailViews Example)。在 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];

现在我的想法不是每次都初始化视图控制器,只需初始化 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];

在横向模式下一切正常,但在纵向模式下,当从第一个详细视图控制器切换到第二个,然后到第一个,然后想要切换到第二个时,会出现错误。出现以下消息:由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“无法从没有窗口的视图中呈现弹出窗口。”

从昨天晚上开始,我试图解决这个问题,但我没有找到解决方案。有人出主意吗?

干杯,多米尼克

【问题讨论】:

【参考方案1】:

我有一个类似的问题,但我发现这个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;

【讨论】:

以上是关于在 Apples MultipleDetailViews 示例中加载已经初始化的 DetailViewControllers的主要内容,如果未能解决你的问题,请参考以下文章

Pick apples 第三届acm省赛

Harvest of Apples

Hdu5303 Delicious Apples 贪心

尝试更新数据框

HDU 6333:Harvest of Apples

hdu 6406Taotao Picks Apples