响应iPhone 6+旋转——traitCollectionDidChange:对导航控制器调用两次



我使用UISplitViewController。我想在用户将iPhone 6 Plus旋转成竖屏而看不到任何细节时显示一个空的选择细节场景。(所有其他设备的行为都是可预测的。只有6 Plus可以改变外观。)我现在使用分屏视图委托它涉及到一些奇怪的查询,但这不是重点。

我想知道iPhone 6是否可以旋转成横向。

我想到的最好的主意是:对特质环境的变化做出反应。主视图控制器一直保持紧凑,只有它的父导航视图控制器从紧凑变为常规,然后再变回来。(当然还有UIWindow)

当使用分屏视图控制器时,对于UINavigationController在"Master"中的子类,traitCollectionDidChange:将在使用iPhone 6 Plus并旋转到横向时被调用两次。返回时调用一次

willTransitionToTraitCollection:withTransitionCoordinator:甚至分别被调用了3次和1次。

我想那是因为在横屏中你可以看到两个视图控制器并排在一起。对我来说,UINavigationController接收子视图控制器的调用是没有意义的。

由于UITraitCollections不包含有关哪个视图控制器受影响的信息,我无法确定环境是否从常规到紧凑的水平大小可靠地改变。其中一个trait集合将报告正确的新值,但我无法将它们彼此区分开来。

你如何解决这个问题,现在回调调用了不同的值多次?

我知道这是一个旧的线程,但我在网上找不到同样问题的解决方案,所以这里是我的两分钱。

UISplitViewController是一个容器视图控制器。所以它被认为是"显示的"即使它上面有视图控制器。在苹果的文档中说:

"视图控制器将trait更改消息转发给它们的子视图控制器。表示控制器将特征更改转发给它们所呈现的视图控制器。"

因此,每当你在分屏视图控制器的size类中引入一个变化时,它会调用它的委托和它的两个子类的委托。

查看更多信息:https://developer.apple.com/reference/uikit/uicontentcontainer/1621511-willtransitiontotraitcollection

编辑:我只是注意到,我没有充分解释为什么UISplitViewController被调用三次。如果willTransitionToTraitCollection:withTransitionCoordinator:没有在呈现的视图中实现,它可能遵循Apple为它设置的约定:

"如果你在自己的对象中重写这个方法,总是在你的实现中调用super,这样UIKit就可以将trait的更改转发给相关的呈现控制器和任何子视图控制器。"

我认为它背后的想法是,在改变一个子视图控制器的traitCollection时,你可能想要改变它的布局和/或兄弟姐妹的数量。为此,子控制器中的任何更改都必须调用容器,以便它知道发生了什么并进行相应的调整。但是,它无法跟踪哪些更改与其他更改重叠,因此所有更改都被注册。

我的解决方案是处理在子视图控制器(UINavigationControllers在我的情况下),而不是通过子类化splitViewController和添加转换逻辑的变化

最新更新