5

我有一个自定义容器视图控制器:ContainerVC. 它的工作是呈现两个内容视图控制器之一:ContentPortraitVCContentLandscapeVC,取决于当前方向(尽管容器选择其视图的原因并不重要,我想)。ContentPortraitVC,在某个时候弹出ContentModalDetailVC

因此,这里有两种不同的方法可以在工作中显示新内容:

  • 父子关系(通过 发起addChildViewController并通过 删除removeFromParentViewController),

  • 呈现-呈现关系(通过 发起presentViewController和通过 移除dismissViewController)。

如果ContainerVC添加ContentPortraitVC,然后呈现ContentModalDetailVC,然后ContainerVC决定切换到ContentLandscapeVC,则ContentModalDetailVC保持可见(为什么在删除其父级时不删除它?)

但是,当ContentPortraitVC要求删除 时ContentModalDetailVC,什么也没有发生。模态显示保持不变。到底是怎么回事?

4

2 回答 2

5
  1. 当您使用addChildViewController添加ContentPortraitVC

    一个。ContentPortraitVC获取其属性parentViewController集。

    湾。然后(根据 Apple 文档)您必须手动显示ContentPortraitVC' 视图。如果您遵循文档,您可以通过将其添加为顶级视图的项来执行此操作。ControllerVC

  2. 然后ContentPortraitVC调用presentViewControllerdisplay ContentModalDetailVC

    一个。这将设置它的presentingViewController属性(在调试器中显示为_parentModalViewControllerivar - 注意 ivar 与属性不同),并设置(谁的 ivar 是)的presentedModalViewController属性。ContentPortraitVC_childModalViewcontroller

    湾。视图方面,在 iPhone 上,ContentModalDetailVC的视图将完全取代 和 的视图ContentPortraitVCContainerVC因此只有模态视图控制器的视图可见。(在 iPad 上,它将新 UI 分层在顶部,但作为 ' 的视图的兄弟ControllerVC而后者又是ContentPortraitVC' 的视图的父级)。

  3. 所以现在,你从 过渡ContentPortraitVCContentLandscapeVC

    一个。IOS 有点神奇。它知道您要删除的东西 ( ContentPortraitVC) 具有presentedViewController当前活动状态,因此它会更改其父项。它将值设置为nilon ContentPortraitVC,获取子视图( the ContentModalDetailVC)并将其父视图设置为新视图(ContentLandscapeVC)。所以现在呈现模态视图的视图控制器不再是它的呈现视图控制器。就好像ContentLandscapeVC一开始就呈现了一样!

    湾。在视图方面,您可以按照 Apple 文档将视图从 更改ContentPortraitVCContentLandscapeVC。但是您只是在更改视图的子ControllerVC视图。在 iPhone 上,模态视图控制器仍然是唯一显示的内容,因此进行更改不会在屏幕上执行任何操作。在 iPad 上,确实如此(尽管您可能不会看到它,因为模态视图通常是全屏的)。

  4. 现在你来关闭模态视图。大概您在 中执行此操作ContentPortraitVC,但它不再引用它所呈现的东西。所以调用[self dismissViewController...什么都不做,因为ContentPortraitVC不再呈现任何东西,对此的责任已经转嫁给ContentLandscapeVC.

所以这就是发生的事情和原因。以下是如何处理它。

  1. ContentPortraitVC当您从 更改为时,您可以手动重新连接委托ContentLandscapeVC,因此后者是试图关闭模态控制器的委托。

  2. 您可以让模态控制器自行关闭[self dismissModalControllerAnimated:YES completion:nil]。如果这看起来很奇怪,我将询问并回答另一个关于为什么会起作用的问题(IOS 怎么知道要解雇哪个?)。

  3. 你可以让ControllerVC那个弹出模态视图并负责删除它。

于 2013-08-04T20:36:51.237 回答
2

如果你检查presentingViewControllerContentModalDetailVC你会看到它实际上是由ContainerVC而不是呈现的ContentPortraitVC

要解决此问题,您只需definesPresentationContextContentPortraitVC.

这将告诉ContentPortraitVC处理模态表示,而不是将响应者链传递给定义表示上下文的下一个视图控制器(默认情况下是您的根视图控制器)。

您可能还想ContentLandscapeVC定义上下文以避免同样的问题。

由于两个子控制器都定义了自己的表示上下文,当ContainerVC决定交换孩子时,任何模态模态都会与呈现它的孩子一起从新层次结构中删除。无需在交换之前做一些骇人听闻的事情来尝试解散:)

编辑:我应该补充一点,呈现的视图控制器必须将其modalPresentationStyle设置为currentContextor overCurrentContext

于 2016-07-02T18:07:55.697 回答