模态和子视图控制器如何交互? [英] How do Modal and Child View Controllers interact?
问题描述
我有一个自定义容器视图控制器: 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?
推荐答案
-
当你使用
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.
-
当您从
ContentPortraitVC更改时,您可以手动重新连接该委托/ code>到
ContentLandscapeVC
,所以后者是试图解雇模态控制器的那个。
You can rewire the delegate manually when you change from
ContentPortraitVC
toContentLandscapeVC
, 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屋!