最近在做橫豎屏切換的時候,發(fā)現(xiàn)一個crash,是一個平時沒有注意到的點。
UIApplicationInvalidInterfaceOrientation', reason: 'preferredInterfaceOrientationForPresentation 'landscapeLeft' must match a supported interface orientation: 'portrait'!
從描述上看,錯誤很明顯,我們從方法的描述上看看。
Returns the interface orientation to use when presenting the view controller.
The system calls this method when presenting the view controller full screen. When your view controller supports two or more orientations but the content appears best in one of those orientations, override this method and return the preferred orientation.
If your view controller implements this method, your view controller’s view is shown in the preferred orientation (although it can later be rotated to another supported rotation). If you do not implement this method, the system presents the view controller using the current orientation of the status bar.
那么如果supportedInterfaceOrientations和preferredInterfaceOrientationForPresentation返回的內(nèi)容不符,是不是就會crash,經(jīng)過試驗的確會crash。
但是我們在dismiss的時候呢,經(jīng)過試驗表明,也是會crash的,特別是preferredInterfaceOrientationForPresentation返回的是UIApplication.shared.statusBarOrientation時,是一個非常容易被忽略的問題。
那么push呢?表現(xiàn)是怎么樣的?
經(jīng)過試驗,在pop的時候,如果橫豎屏狀態(tài)不一致,并不會crash,但是轉(zhuǎn)場動畫采用了系統(tǒng)默認(rèn)的了,不會進(jìn)入轉(zhuǎn)場動畫的delegate。
所以,如果需要做流暢的轉(zhuǎn)場以及橫豎屏切換,在一些場合下,還是需要使用present方式,并且需要在雙方都確保supportedInterfaceOrientations和preferredInterfaceOrientationForPresentation的正確。
自定義動畫
在做自定義轉(zhuǎn)場動畫的時候,可以注意到,如果是從豎屏進(jìn)入橫屏的動畫過程中,橫豎屏的狀態(tài)是正確的,但是橫豎屏狀態(tài)只能存在一個,也就是[UIDevice currentDevice].orientation,那么系統(tǒng)是怎么做到的呢。
重寫UIViewControllerAnimatedTransitioning中的動畫方案- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext,在此時獲取屏幕方向[UIApplication sharedApplication].statusBarOrientation,發(fā)現(xiàn)已經(jīng)轉(zhuǎn)換到下一個controller的方向了,那么前一個controller為什么顯示正常呢。我們看一下前一個fromController.view.transform,發(fā)現(xiàn)他并不是CGAffineTransformIdentity,這樣就一目了然了。系統(tǒng)在屏幕轉(zhuǎn)向變化的時候,會把上一個視圖自動旋轉(zhuǎn)90度,這樣就可以無縫的轉(zhuǎn)場動畫。
那么另一個問題是,此時的controller的生命周期會是怎么樣的。經(jīng)過嘗試,此時已經(jīng)在viewWillAppear:和viewWillDisappear之后了,符合我們的預(yù)期。