【问题标题】:UISplitViewController Cannot Change the Master View Controller?UISplitViewController 无法更改主视图控制器?
【发布时间】:2010-05-04 08:12:02
【问题描述】:

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

我正在使用以下内容:

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

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

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

其实我可以设置主视图控制器,横向模式下正确看到new viewController,旋转back为纵向,popover中使用的viewcontroller为还是旧的。

这是一个错误吗?

【问题讨论】:

    标签: iphone ipad uiviewcontroller uisplitviewcontroller


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

      我们刚刚遇到了完全相同的问题。有时我想知道 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 被告知弹出框控制器将呈现视图控制器时,您还必须设置弹出框的 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,但稍后,如果显示包含的 viewcontroller再次,将 viewDidDisappear 等延迟消息发送到已释放的视图/控制器(此时可能已被释放)。

      【讨论】:

      • UISplitViewController 存在大量缺陷。这似乎是最糟糕的情况之一。从 iOS SDK 5.1 开始,我仍然看到这些问题。但是,似乎涉及使用 UINavigationController 作为根主视图的解决方法在此版本中确实有效。
      • 哇,这么晚了还是那么糟糕?感谢丹更新我们。
      猜你喜欢
      • 2017-10-14
      • 2017-04-05
      • 1970-01-01
      • 2016-07-18
      • 2014-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多