UISplitViewController无法更改主视图控制器?

时间:2010-05-04 08:12:02

标签: iphone ipad uiviewcontroller uisplitviewcontroller

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

我使用以下内容:

  

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

这正确地改变了主视图控制器,就像在横向模式下一样。但是似乎在纵向模式下更改了用于弹出窗口的viewcontroller。

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

实际上,我可以设置主视图控制器,在横向模式下正确地看到 new viewController,将后面旋转到纵向,并且popover中使用的viewcontroller是仍旧旧的。

这是一个错误吗?

2 个答案:

答案 0 :(得分:2)

如果有人正在寻找这个问题的解决方案(或一个单词),我遇到了类似的问题并在此处进行了解决:Changing the master view in Split View does not update the popover in portrait

基本上,我使用导航控制器作为主视图控制器,并在该导航控制器中按下/加载视图控制器,以便在主视图中更改视图控制器,同时仍然在纵向中显示正确的viewcontroller,在弹出窗口中图。

答案 1 :(得分:1)

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

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

问题是当您在拆分视图中替换主视图控制器时,UISplitViewController中的代码不会更新其弹出控制器的contentViewController属性。结果是弹出控制器在过时视图控制器上仍然有一个句柄,在纵向模式下会出现旧的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被告知弹出控制器将要呈现视图控制器时,你还必须设置popover的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,稍后您将通过nav控制器内的根视图,而不是nav控制器本身。就我所见,UISplitViewController无法以任何可行的方式处理更改主视图。

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

更新2

我放弃了。上面第一次更新的方法也存在缺陷;旋转时我仍然遇到问题。基本上,似乎如果您使用UISplitViewController,则不应尝试更改主视图控制器(即使您在主视图(例如弹出窗口)再次被隐藏时切换主视图)。摆弄主视图中的UINavigationController的内容(主视图显示时显示)似乎没问题,但除此之外的任何内容都会导致问题后出现问题。

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