我实现了 UIPageViewController
的自定义子类,它正在分页另一个自定义 UIViewController 子类的几个实例。相当标准。我不会也不能使用自动布局。
我想在这两种情况下支持轮换
- ALL 当应用程序允许所有屏幕方向时
- 仅当应用中只允许肖像时才使用肖像。
当允许所有方向时,一切都完美无缺。由于旋转实际上是窗口上的变换,分页 Controller 中的所有自定义分页 Controller 都很好地“旋转”(它们只是有效地调整到新的边界),我正在利用 viewWillTransitionToSize
并且我我正在通过旁边的动画对 subview 进行一些自定义布局。很漂亮。
第二个 PORTRAIT ONLY 案例的表现不是那么漂亮。由于在这种情况下不支持旋转,我正在监听 UIDeviceOrientationDidChangeNotification
通知,并手动旋转 Root View 。
我只是使用 UIView.animateWithDuration... 并将仿射变换应用于 PagingController 的 Root View 。
UIView.animateWithDuration(0.3, delay: 0, options: UIViewAnimationOptions.CurveLinear, animations: { () -> Void in
self.view.transform = self.rotationTransform()
self.view.bounds = self.rotationAdjustedBounds()
})
{ finished in
}
转换实际上是一个 CGAffineTransformMakeRotation 调用。没什么特别的。 self
是分页 Controller 。
它有效但由于某种原因旋转非常难看,看起来 anchor 是上帝知道在哪里,并且不尊重某些 subview 的自动调整大小掩码。这没有任何意义,因为布局是以一致的方式完成的,证明是在 ALL 情况下的旋转,一切都完美地调整到旋转。
我不能使用允许全局旋转然后在除此 Controller 之外的任何地方都退出纵向的方法。该应用程序很大,出于非技术原因这是不可能的,利益相关者根本不允许我这样做。
我的问题是 - 考虑到这些限制,您能否推荐一种更好的方法 -> 通过手动轮换收听通知?
最佳答案
我解决了这个问题,让其他人知道以供引用很有趣。 我必须改变两件事:
1)在动画方法中触发一个layout pass
UIView.animateWithDuration(0.3, delay: 0, options: UIViewAnimationOptions.CurveLinear, animations: { () -> Void in
self.view.transform = self.rotationTransform()
self.view.bounds = self.rotationAdjustedBounds()
self.view.setNeedsLayout()
self.view.layoutIfNeeded()
})
2) 修复实际的布局便利方法。
请记住,我正在手动进行布局。这些布局方法都是从 viewDidLayoutSubviews 调用的,并且只是构造代码以使其更具可读性,这里没有什么特别的。我犯了一个愚蠢的错误,即根据其他值计算大小和框架等值...其中一些其他值是 .frame
属性。但是当应用变换时 frame 是未定义的,所以我将所有这些出现改为 bounds。
它现在的行为方式与内置旋转完全相同。
PS:我认为它对于内置旋转效果很好,因为没有直接应用于 View 的变换。因此,没有(根) View 参与会对其自身应用变换的布局计算。这就是为什么从 Root View 派生值仍然有效的原因。
关于ios - 为什么这两种轮换方法给我不同的用户体验?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35915227/