6

我正在尝试更改 UISplitViewController 中的主视图控制器(显示在纵向弹出窗口中,横向显示在左侧)。我想在作为两个不同 UIViewController 之一的主视图控制器之间切换(取决于在我的应用程序其他地方采取的操作)。

我正在使用以下内容:

mySplitViewController.viewControllers = [NSArray arrayWithObjects:newMasterController, detailController, nil];

正如您在横向模式下所期望的那样,这会正确更改主视图控制器。然而,它似乎并没有改变纵向模式下用于弹出框的视图控制器。

我注意到显示此主视图控制器的 barbuttonitem 只是在 splitviewcontroller 上调用 showMasterInPopover:,因此希望它也可以在纵向模式下工作,但事实并非如此。

事实上,我可以设置主视图控制器,在横向模式下正确看到新的视图控制器,旋转纵向,弹出窗口中使用的视图控制器仍然是旧的。

这是一个错误吗?

4

2 回答 2

2

如果有人正在寻找这个问题的解决方案(或解决方案),我遇到了类似的问题并在这里解决了:更改拆分视图中的主视图不会更新纵向的弹出框

基本上,我为主视图控制器使用了导航控制器,并在该导航控制器中推送/弹出视图控制器,以便在主视图中更改视图控制器,同时在弹出视图中仍以纵向显示正确的视图控制器。

于 2011-12-23T08:37:25.747 回答
1

更新:请阅读底部的最终更新!下面的原始答案+更新可能没有用!

我们刚刚遇到了完全相同的问题。有时我想知道 Apple 是否真的用任何类似于现实用例的东西来测试他们编写的类,因为 UISplitViewController 并不是他们最好的时刻。

问题是,当您在拆分视图中替换主视图控制器时,UISplitViewController 内的代码不会更新其弹出框控制器的 contentViewController 属性。结果是popover控制器仍然有一个过期视图控制器的句柄,导致在纵向模式下出现旧的UI,甚至内存错误。

这是我们的解决方法。

我将假设您有一个符合 UISplitViewControllerDelegate 的类,它将 popoverController 存储为类属性(请参阅 UISplitViewController 的标准示例代码)。

在设置新的主视图控制器时,您还需要更新 contentViewController,如下所示:

mySplitViewController.viewControllers
    = [NSArray arrayWithObjects:newMasterController, detailController, nil];

// in the cases where the uisplitview has already shown a popovercontroller,
// we force the popovercontroller to update its content view controller. 
// This ensures any old content view in popover actually gets released by 
// the popovercontroller.
if (popoverController) {
    [popoverController setContentViewController:theMasterViewController 
                                animated:NO];       
}

当您的 UISplitViewControllerDelegate 被告知弹出框控制器将呈现视图控制器时,您还必须设置弹出框的 contentViewController:

- (void)splitViewController:(UISplitViewController*)svc 
        popoverController:(UIPopoverController*)pc 
        willPresentViewController:(UIViewController *)aViewController 
{
    // set the popoverController property - as per Apple's sample code
    self.popoverController = pc;

    // THE LINE BELOW IS THE NEW LINE!
    [popoverController setContentViewController:aViewController animated:NO];

是的,我知道上面的代码看起来很疯狂,你想知道为什么苹果不能自己设置内容视图控制器。但他们显然没有,这就是解决方法。

更新

上面的方案,通过设置内容视图,结果证明是行不通的。例如,如果您将内容视图设置为 uinavigationcontroller,稍后您将通过导航控制器内部的根视图,而不是导航控制器本身。据我所知,UISplitViewController 只是不处理以任何可行的方式更改主视图。

我目前的解决方法是安装 UINavigationController 作为主视图,并更改该导航控制器的根视图控制器。所以我可以在某种程度上改变“后门”的主视图。

更新 2

我放弃。上面第一次更新中的方法也有缺陷;我在轮换时仍然遇到问题。基本上,如果您使用 UISplitViewController,您似乎不应该尝试对主视图控制器进行任何更改(即使您在主视图(例如作为弹出框)再次隐藏时切换主视图)。在主视图中摆弄 UINavigationController 的内容(当主视图显示时)看起来会没问题,但除此之外的任何事情都会导致问题接踵而至。

技术说明:我认为问题源于 Apple 处理 UI 的一个明显弱点:即,一旦隐藏或从视图中删除,Apple 代码将在 UIViews 和控制器上调用 release,但稍后,如果再次显示包含的视图控制器,则发送延迟消息,如 viewDidDisappear 到已发布的视图/控制器(此时可能已被释放)。

于 2010-11-19T11:49:48.760 回答