之前的專案採用的是在一個只支援Portrait的ViewController上,present一個只支援Landscape的ViewController,通過改寫ViewController之間的轉場動畫,來達到全屏全屏的方案.這種方案有很多坑在裡面,而且也不夠簡潔.
改進:
後面經過調查發現一種簡潔的實現方式,利用SizeClass加強制螢幕旋轉的方式就能夠實現. 使用SizeClass+xib就能完成整個橫豎屏切換介面的搭建
storyboard橫豎屏介面搭建
一個介面對應橫屏狀態和豎屏兩種狀態 橫屏狀態為:wC*hR (width Compact ,height Regular) 豎屏狀態為:hC (width Any,height Compact) ,width為Any的原因是7P位(wR*hC) 其他機型為(wC*hC)
豎屏顯示View
上圖是新增一個只在豎屏顯示View,首先選中任意個手機機型,然後選中Vary for Traits的Width和Height兩個選項,把約束條件固定為wC*hR,然後在介面新增View,新增的View就只在豎屏下顯示,這種狀態新增約束也只在豎屏下顯示. 紅框就表示該view只在wC*hR下顯示,如果是在所有介面下顯示第一行Instailler會被勾選橫屏顯示View
橫屏View新增方法類似,首先選中任意個手機機型,然後選中Vary for Traits的Height選項,把約束條件固定為hC,然後在介面新增View,新增的View就只在橫屏下顯示,新增的約束也只在橫屏有效最終新增效果
中間橫豎屏切換的時候過渡動畫由系統自動完成.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來儲存當前的狀態,這裡有個坑,如果只是簡單的返回UIInterfaceOrientationMaskAll,如果應用退到後臺或者鎖屏返回來,介面會被重置為豎屏狀態,所以介面只能為UIInterfaceOrientationMaskLandscape,這樣才不會被重置為豎屏,才能保持前後狀態一致.
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的方式呼叫了系統的螢幕切換方法,屬於間接呼叫私有API,經過多方詢問,可以通過蘋果稽核,在蘋果早期版本是有公開的螢幕旋轉方法的,後來變成了私有API.具體原因不詳.
這樣通過storyboard,在不需要新增任何介面程式碼的情況下完成了螢幕旋轉的需求,而且效果還不錯.如果要全屏,可以將其中的一個View的約束改成全屏就可以了,