模态和子视图控制器如何交互? [英] How do Modal and Child View Controllers interact?

查看:95
本文介绍了模态和子视图控制器如何交互?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义容器视图控制器: ContainerVC 。它的工作是提供两个内容视图控制器之一: ContentPortraitVC ContentLandscapeVC ,具体取决于当前的方向(尽管它无论如何容器选择它的视图,我推测)。 ContentPortraitVC ,在某些时候弹出 ContentModalDetailVC

I have a custom container view controller: ContainerVC. Its job is to present one of two content view controllers: ContentPortraitVC or ContentLandscapeVC, depending on the current orientation (though it doesn't matter why the container chooses its view, I presume). ContentPortraitVC, at some point pops up ContentModalDetailVC.

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

So there are two different methods of displaying new content at work here:


  • 父母与子女的关系(通过 addChildViewController 并通过 removeFromParentViewController 删除,

呈现和呈现的关系(通过 presentViewController 发起并通过 dismissViewController 删除)。

the presenting-and-presented relationship (instigated via presentViewController and removed via dismissViewController).

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

If the ContainerVC adds the ContentPortraitVC, which then presents the ContentModalDetailVC, and then the ContainerVC decides to switch to the ContentLandscapeVC, the ContentModalDetailVC stays visible (why is it not removed when its parent is removed?)

但是,当要求 ContentPortraitVC 删除内容时ModalDetailVC ,没有任何反应。模态显示保持不变。发生了什么?

But then, when the ContentPortraitVC is asked to remove the ContentModalDetailVC, nothing happens. The modal display stays put. What is going on?

推荐答案


  1. 当你使用 addChildViewController时添加 ContentPortraitVC

a。 ContentPortraitVC 获取其 parentViewController 属性集。

a. The ContentPortraitVC gets its parentViewController property set.

b。然后(根据Apple文档)必须手动显示 ContentPortraitVC 的视图。如果您按照文档执行此操作,请将其添加为 ControllerVC 的顶级视图的

b. You then (as per the Apple documentation) have to manually display the ContentPortraitVC's view. If you follow the documentation you do this by adding it as a child of the ControllerVC's top level view.

ContentPortraitVC 然后调用 presentViewController 显示 ContentModalDetailVC

a。这将设置其 presentsViewController 属性(在调试器中显示为 _parentModalViewController ivar - 注意ivar与属性),并设置 ContentPortraitVC presentsModalViewController 属性(谁的ivar是 _childModalViewcontroller )。

a. This sets its presentingViewController property (in the debugger this is shown as the _parentModalViewController ivar -- note the ivar is different from the property), and sets the presentedModalViewController property of the ContentPortraitVC (who's ivar is _childModalViewcontroller).

b。明智地看,在iPhone上, ContentModalDetailVC 的视图将完全取代 ContentPortraitVC ContainerVC ,因此只有模态视图控制器的视图才可见。 (在iPad上,它将新UI分层到顶部,但作为 ControllerVC 的视图的兄弟视图,而后者又是父视图 ContentPortraitVC 的视图。

b. Views wise, on iPhone, the ContentModalDetailVC's view will completely replace the views from ContentPortraitVC and ContainerVC, so only the modal view controller's view will be visible. (on iPad, it layers the new UI over the top, but as a sibling of the ControllerVC's view, which in turn is the parent of ContentPortraitVC's view).

现在,你从过渡ContentPortraitVC ContentLandscapeVC

a。 IOS做了一些魔术。它知道你要删除的东西( ContentPortraitVC )当前有一个 presentsViewController ,所以它改变了它的父节点。它在 ContentPortraitVC 上将值设置为 nil ,接受子项( ContentModalDetailVC )并将其父级设置为新视图( ContentLandscapeVC )。所以现在呈现模态视图的视图控制器不再是它呈现的视图控制器。好像 ContentLandscapeVC 首先出现它!

a. IOS does a bit of magic. It knows that the thing you are removing (ContentPortraitVC) has a presentedViewController currently active, so it changes its parent. It sets the value to nil on ContentPortraitVC, takes the child (the ContentModalDetailVC) and sets its parent to the new view (ContentLandscapeVC). So now the view controller that presented the modal view is no longer its presenting view controller. It is as if ContentLandscapeVC presented it in the first place!

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

b. In terms of views, you follow the Apple docs to change over the view from ContentPortraitVC to ContentLandscapeVC. But you are simply changing the subviews of ControllerVC's view. On iPhone, the modal view controller is still the only thing being displayed, so making the change doesn't do anything on screen. On iPad, it does (though you probably won't see it, as the modal view is usually full screen).

现在你来解雇模态视图。大概是你在 ContentPortraitVC 中做到这一点,但它不再引用它所呈现的东西。所以调用 [self dismissViewController ... 什么都不做,因为 ContentPortraitVC 不再提供任何内容,对此负有责任传递给 ContentLandscapeVC

Now you come to dismiss the modal view. Presumably you do this in ContentPortraitVC, but it no longer has any reference to the thing it presented. So calling [self dismissViewController... does nothing, because ContentPortraitVC is no longer presenting anything, responsibility for that has been passed on to ContentLandscapeVC.

这就是发生的事情,为什么。以下是该怎么做。

So that's what happens and why. Here's what to do about it.


  1. 当您从 ContentPortraitVC更改时,您可以手动重新连接该委托/ code>到 ContentLandscapeVC ,所以后者是试图解雇模态控制器的那个。

  1. You can rewire the delegate manually when you change from ContentPortraitVC to ContentLandscapeVC, so the latter is the one that tries to dismiss the modal controller.

你可以让模态控制器用 [self dismissModalControllerAnimated:YES completion:nil] 解雇自己。我将要求并回答另一个问题,为什么这样做有效(IOS如何解释?),如果这看起来很奇怪。

You can have the modal controller dismiss itself with [self dismissModalControllerAnimated:YES completion:nil]. I'm going to ask and answer another question on why that works (how does IOS know which to dismiss?), if that seems strange.

你可以让 ControllerVC 成为弹出模态视图并负责将其删除的人。

You can have the ControllerVC be the one that pops up the modal view and be responsible for removing it.

这篇关于模态和子视图控制器如何交互?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆