之前的項目采用的是在一個只支持Portrait的ViewController上,present一個只支持Landscape的ViewController,通過改寫ViewController之間的轉(zhuǎn)場動畫,來達到全屏全屏的方案.這種方案有很多坑在里面,而且也不夠簡潔.
改進:
后面經(jīng)過調(diào)查發(fā)現(xiàn)一種簡潔的實現(xiàn)方式,利用SizeClass加強制屏幕旋轉(zhuǎn)的方式就能夠?qū)崿F(xiàn).
使用SizeClass+xib就能完成整個橫豎屏切換界面的搭建
storyboard橫豎屏界面搭建
一個界面對應橫屏狀態(tài)和豎屏兩種狀態(tài)
橫屏狀態(tài)為:wC*hR (width Compact ,height Regular)
豎屏狀態(tài)為:hC (width Any,height Compact) ,width為Any的原因是7P位(wR*hC) 其他機型為(wC*hC)
豎屏顯示View

上圖是添加一個只在豎屏顯示View,首先選中任意個手機機型,然后選中Vary for Traits的Width和Height兩個選項,把約束條件固定為wC*hR,然后在界面添加View,添加的View就只在豎屏下顯示,這種狀態(tài)添加約束也只在豎屏下顯示.

紅框就表示該view只在wC*hR下顯示,如果是在所有界面下顯示第一行Instailler會被勾選
橫屏顯示View

橫屏View添加方法類似,首先選中任意個手機機型,然后選中Vary for Traits的Height選項,把約束條件固定為hC,然后在界面添加View,添加的View就只在橫屏下顯示,添加的約束也只在橫屏有效
最終添加效果


中間橫豎屏切換的時候過渡動畫由系統(tǒng)自動完成.
AppDelegate設置
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(nullable UIWindow *)window {
if ([window.rootViewController isKindOfClass:[ViewController class]]) {
ViewController *viewcontroller = (ViewController *)window.rootViewController;
if (viewcontroller.isFullScreen) {
return UIInterfaceOrientationMaskLandscape;
} else {
return UIInterfaceOrientationMaskPortrait;
}
} else {
return UIInterfaceOrientationMaskPortrait;
}
}
isFullScreen來存儲當前的狀態(tài),這里有個坑,如果只是簡單的返回UIInterfaceOrientationMaskAll,如果應用退到后臺或者鎖屏返回來,界面會被重置為豎屏狀態(tài),所以界面只能為UIInterfaceOrientationMaskLandscape,這樣才不會被重置為豎屏,才能保持前后狀態(tài)一致.
ViewController設置
- (IBAction)change:(id)sender {
if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait) {
self.isFullScreen = YES;
NSNumber *orientationUnknown = [NSNumber numberWithInt:UIInterfaceOrientationUnknown];
[[UIDevice currentDevice] setValue:orientationUnknown forKey:@"orientation"];
NSNumber *orientationTarget = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
[[UIDevice currentDevice] setValue:orientationTarget forKey:@"orientation"];
} else {
self.isFullScreen = NO;
NSNumber *orientationUnknown = [NSNumber numberWithInt:UIInterfaceOrientationUnknown];
[[UIDevice currentDevice] setValue:orientationUnknown forKey:@"orientation"];
NSNumber *orientationTarget = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:orientationTarget forKey:@"orientation"];
}
}
這里采用KVO的方式調(diào)用了系統(tǒng)的屏幕切換方法,屬于間接調(diào)用私有API,經(jīng)過多方詢問,可以通過蘋果審核,在蘋果早期版本是有公開的屏幕旋轉(zhuǎn)方法的,后來變成了私有API.具體原因不詳.
這樣通過storyboard,在不需要添加任何界面代碼的情況下完成了屏幕旋轉(zhuǎn)的需求,而且效果還不錯.如果要全屏,可以將其中的一個View的約束改成全屏就可以了,