ios - 在 Apples MultipleDetailViews Example 中加载已经初始化的 DetailViewControllers

标签 ios ipad uisplitviewcontroller

Apple 在其 iOS 开发网站上展示了一个示例,说明如何使用具有不同细节 View 的 Split View (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];
}

现在我的想法不是每次都初始化 View Controller ,而是在 viewDidLoad(以及 header )中初始化 Controller ,并在选择单元格时传递它们的引用:

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

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

从昨天晚上开始,我一直在努力解决这个问题,但我没有找到解决方案。有人有想法吗?

干杯,多米尼克

最佳答案

我遇到了类似的问题,但我发现了这个 post这证明了在设置 splitView 的 View Controller 之前必须从先前的 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;

}

关于ios - 在 Apples MultipleDetailViews Example 中加载已经初始化的 DetailViewControllers,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6339991/

相关文章:

ios - React Native 响应式 View Iphone x

iphone - iPad 上的 groupTableViewBackgroundColor 有什么问题?

ios - 为什么在 nib 中创建 UIGestureRecognizer 子类会导致使用 UISplitViewController 崩溃

uitabbarcontroller - Tabbarcontrol中UISplitview的旋转

iphone - 他们是如何在iPhone app中实现垂直过渡的动画的?

ios - 如何访问 xcode 项目中的 sqlite 文件?

ios - "modifying layer that is being finalized"弹出导航 Controller 时出错

ipad - iPad 上的 SVG 交互

objective-c - UISplitViewController EXC_BAD_ACCESS 使用 ARC 旋转

ios - 我应该为 CFBundleVersion 和 CFBundleShortVersionString 使用什么值?