最近在做横竖屏切换的时候,发现一个crash,是一个平时没有注意到的点。
1 | UIApplicationInvalidInterfaceOrientation', reason: 'preferredInterfaceOrientationForPresentation 'landscapeLeft' must match a supported interface orientation: 'portrait'! |
从描述上看,错误很明显,我们从方法的描述上看看。
1 | Returns the interface orientation to use when presenting the view controller. |
那么如果supportedInterfaceOrientations
和preferredInterfaceOrientationForPresentation
返回的内容不符,是不是就会crash,经过试验的确会crash。
但是我们在dismiss
的时候呢,经过试验表明,也是会crash的,特别是preferredInterfaceOrientationForPresentation
返回的是UIApplication.shared.statusBarOrientation
时,是一个非常容易被忽略的问题。
那么push呢?表现是怎么样的?
经过试验,在pop的时候,如果横竖屏状态不一致,并不会crash,但是转场动画采用了系统默认的了,不会进入转场动画的delegate。
所以,如果需要做流畅的转场以及横竖屏切换,在一些场合下,还是需要使用present方式,并且需要在双方都确保supportedInterfaceOrientations
和preferredInterfaceOrientationForPresentation
的正确。
自定义动画
在做自定义转场动画的时候,可以注意到,如果是从竖屏进入横屏的动画过程中,横竖屏的状态是正确的,但是横竖屏状态只能存在一个,也就是[UIDevice currentDevice].orientation
,那么系统是怎么做到的呢。
重写UIViewControllerAnimatedTransitioning
中的动画方案- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
,在此时获取屏幕方向[UIApplication sharedApplication].statusBarOrientation
,发现已经转换到下一个controller的方向了,那么前一个controller为什么显示正常呢。我们看一下前一个fromController.view.transform
,发现他并不是CGAffineTransformIdentity
,这样就一目了然了。系统在屏幕转向变化的时候,会把上一个视图自动旋转90度,这样就可以无缝的转场动画。
那么另一个问题是,此时的controller的生命周期会是怎么样的。经过尝试,此时已经在viewWillAppear:
和viewWillDisappear
之后了,符合我们的预期。