UIViewController 包含方向更改

Posted

技术标签:

【中文标题】UIViewController 包含方向更改【英文标题】:UIViewController containment orientation changes 【发布时间】:2012-07-08 02:26:46 【问题描述】:

我有一个 UIViewController 可以说它称为 A。在 A 中,我添加了另一个 UIViewController 称为 B。我还在 A 上添加了另一个 UIViewController,我们称之为 C。我遇到的问题是,当 C 不是存在(即:未添加到 A 的视图控制器)然后旋转给了我正确的大小,但是当 C 添加到 A 时。然后 UIViewContoroller 的 B 没有收到正确的帧调整。为什么会这样,我该如何解决?

基本上,当我在 B 的 willAnimateToInterfaceRotation 中旋转时,无论方向如何,框架都保持不变。所以说B是纵向的,尺寸是768 x 1004。然后我有一个在A中添加C的按钮(C在B前面)。当我旋转它时,它打印出框架的大小是 768x1004。但是,如果我关闭 C(即:将其从父视图控制器中删除,在本例中为 A)。当我旋转框架时,宽度会相应改变。

【问题讨论】:

【参考方案1】:

更新:

我意识到我可能误解了最初的问题。但要正确回答这个问题,我需要澄清你在说什么。所以,你说:

我有一个 UIViewController 可以说它叫做 A。在 A 中,我添加了 另一个名为 B 的 UIViewController。我还添加了另一个 A 上的 UIViewController,我们称之为 C。

那么,从本质上讲,您已经完成了以下操作?

[A addChildViewController:B];
[B didMoveToParentViewController:A];
[A addChildViewController:C];
[C didMoveToParentViewController:A];

我说对了吗?不管怎样,你继续说:

我遇到的问题是,当 C 不存在时(即:未添加到 A 视图控制器)然后旋转给我正确的大小,

那么,您是说您从未调用过addChildViewController:C 表示一切正常吗?你继续:

... 但是当 C 添加到A。然后UIViewController的B没有收到 正确的框架调整。

那么,你是说如果你调用了addChildViewController:C,并且有transitionFromViewController:B toViewController:C?但如果是这样的话,B 根本不会得到任何轮换事件。当您从 B 过渡到 C 时,我引用 B.view.frame.size 对我来说没有意义。无论如何,这是我最初回答的基础,假设您一定在谈论以下场景:

B & C 通过addChildViewController添加, B 在纵向时最初处于活动状态, 你transitionFromViewController:B toViewController:C, 您将设备旋转到横向,C 获得旋转事件,但 B 没有, 你 transitionFromViewController 回到 B,现在视图控制器 B 接收外观相关的方法,例如 viewWillAppear,但在 C 处于活动状态时将错过任何旋转事件

因此,如果您需要 B 在这种情况下检查基于旋转的逻辑,则必须在 B 的 viewWillAppear 之类的方法期间执行此操作(除非父视图控制器 A 在执行 @987654333 之后显式调用其他内容@)。但我现在意识到你可能并不关心旋转事件的存在与否,而只是当你检查框架时,你会得到奇怪的结果。但我不太明白你描述的场景,所以让我们继续你的问题。

所以,你继续说:

基本上当我在 B 的 willAnimateToInterfaceRotation 中旋转时 无论方向如何,框架都保持不变。所以说B在 纵向,尺寸为 768 x 1004。

好的,我认为我们在那里很好。你继续:

然后我有一个添加按钮 A中的C(C在B的前面)。

你是说你做了transitionFromViewController:B toViewController:C?在视图控制器包含的上下文中,术语“在 B 之前”对我来说没有意义。 C 不会走在 B 前面。你从 B 过渡到 C。

当我旋转它时,它会打印出 帧为 768x1004。

这很奇怪。但是,更重要的是,“768x1004”是什么意思? C.view.frame.size?如果您从 B 过渡到 C,我认为引用 B.view.frame.size 是没有意义的。我不清楚你在说什么报告“768x1004”。

不管怎样,你继续:

但是,如果我解雇 C(即:将其从 父视图控制器,在本例中为 A)。当我旋转框架 宽度会相应变化。

当您说“从父视图控制器中删除它”时,我假设您的意思是:

调用transitionFromViewController:C toViewController:B[C willMoveToParentViewController:nil] 警告 C 它将消失 然后用[C removeFromParentViewController];删除它

如果您能就我上面的解释(或误解)澄清您最初的问题,那么我们确切地知道您在做什么?我确实在容器中看到了一些关于框架尺寸的奇怪东西,但我想确保我首先理解你的问题。

原文:

automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers。说真的,这个方法名是谁想出来的?!?

但这不会将方法发送到非活动视图控制器。看起来您必须对子控制器的viewWillAppear 进行一些方向检查。

注意,如果不是预先加载所有控制器,而是及时加载(有点像标签视图控制器),这个问题就会消失。

【讨论】:

好吧..这个默认是YES,所以它应该自动转发它。为什么我必须在 viewWillAppear 中这样做?那么方向变化会发生什么? @xonegirlz 很抱歉,但我的 automaticForwardAppearanceAndRotationMethodsToChildViewControllers 只是一个与您的原始问题相关的可怕相关方法的笑话/致敬。我的主要观点与该方法无关,而是与我的概念有关,即如果您的容器 A 从子 B 转换到子 C,则该子 B 将不会收到旋转事件,因此,如果您想做旋转逻辑,则必须这样做当你转换回 B 时。但我想我可能严重误解了你的问题,所以请参阅上面我修改后的问题。 @xonegirlz 顺便说一句,我在容器视图对self.view.frame 的理解中肯定看到了一些奇怪的行为。我现在依赖子视图控制器的self.view.frame,它似乎更可靠。我怀疑视图控制器容器在处理旋转事件时存在一些错误。 我在这里用代码示例重新创建了问题***.com/questions/11415436/…我希望在回答你所有的疑问时有点清楚

以上是关于UIViewController 包含方向更改的主要内容,如果未能解决你的问题,请参考以下文章

在不继承 UINavigationController 的情况下以编程方式更改 ViewController 的方向

uiviewcontroller中的设备方向更改[重复]

自定义 UIViewController 未收到有关设备旋转的方向更改通知

如何以编程方式将 UIViewController 的方向更改为横向?

我可以观察 UIViewController 何时更改 interfaceOrientation 吗?

在 SwiftUI 中更改方向时更新 UI