我正在尝试在UISplitViewController中更改主视图控制器(以纵向显示在popover中,在横向中显示在左侧)。我想在主视图控制器之间切换,这是两个不同的UIViewControllers之一(取决于我的应用程序中其他地方采取的操作)。
我使用以下内容:
mySplitViewController.viewControllers = [NSArray arrayWithObjects:newMasterController,detailController,nil];
这正确地改变了主视图控制器,就像在横向模式下一样。但是不似乎在纵向模式下更改了用于弹出窗口的viewcontroller。
我注意到显示这个主视图控制器的barbuttonitem只是在splitviewcontroller上调用showMasterInPopover:所以期望它也可以在纵向模式下工作,但事实并非如此。
实际上,我可以设置主视图控制器,在横向模式下正确地看到 new viewController,将后面旋转到纵向,并且popover中使用的viewcontroller是仍旧旧的。
这是一个错误吗?
答案 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)发送到已发布的视图/控制器(此时可能已取消分配)。