這段時(shí)間做的一個(gè)app吠裆,需求是大部分界面豎屏涂炎,播放器頁面橫屏,網(wǎng)頁播放可橫屏可豎屏赂蕴。查閱了一些資料柳弄,也踩了一些坑, 在這里做一個(gè)總結(jié)。
iOS如何支持旋屏
1. project->target->Deployment Info->Device Orientation
這里的Landscape Left是Device Orientation概说,是指內(nèi)容的方向碧注,即此時(shí)手機(jī)向右旋轉(zhuǎn),home鍵在左邊席怪;而Landscape Right表示手機(jī)向右左旋轉(zhuǎn)应闯,home鍵在右邊
2. 代碼控制
在AppDelegate中添加方法
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
return UIInterfaceOrientationMaskAll;
}
當(dāng)使用代碼控制旋屏方向時(shí),第一點(diǎn)的Device Orientation配置就失效了
關(guān)于旋屏之后狀態(tài)欄消失的問題挂捻,解決辦法是在需要旋屏的UIViewController中重寫3個(gè)方法
//設(shè)置樣式
- (UIStatusBarStyle)preferredStatusBarStyle {
return UIStatusBarStyleDefault;
}
//設(shè)置是否隱藏
- (BOOL)prefersStatusBarHidden {
return NO;
}
//設(shè)置隱藏動(dòng)畫
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
return UIStatusBarAnimationNone;
}
如果不想在ViewController中都去重寫,可以選擇
- 繼承一個(gè)基類ViewController船万,在基類中重寫上述3個(gè)方法
- 新建Category
@implementation UIViewController (StatusBarCategory)
//設(shè)置樣式
- (UIStatusBarStyle)preferredStatusBarStyle {
return UIStatusBarStyleDefault;
}
//設(shè)置是否隱藏
- (BOOL)prefersStatusBarHidden {
return NO;
}
//設(shè)置隱藏動(dòng)畫
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
return UIStatusBarAnimationNone;
}
@end
如果風(fēng)格統(tǒng)一刻撒,推薦第二種寫法,盡量減少使用繼承耿导;若需要定制狀態(tài)欄声怔,可以使用第一種方案
那么現(xiàn)在來說說需要解決旋屏的需求
通常app大部分界面豎屏,有的界面強(qiáng)制橫屏舱呻,如播放器醋火,而有的界面支持橫豎屏,如UIWebView
因?yàn)樗械男炼紩逜ppDelegate的方法
-(UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window;
所以在AppDelegate.h暴露2個(gè)參數(shù)
@property (nonatomic, assign) BOOL allowRotate;
@property (nonatomic, assign) UIInterfaceOrientationMask interfaceOrientation;
AppDelegate.m中
//初始化參數(shù)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.allowRotate = NO;
self.interfaceOrientation = UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
return self.allowRotate?self.interfaceOrientation:UIInterfaceOrientationMaskPortrait;
}
在需要旋屏的ViewController中
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
((AppDelegate *)[UIApplication sharedApplication].delegate).allowRotate = YES;
//需要旋屏支持的方向
((AppDelegate *)[UIApplication sharedApplication].delegate).interfaceOrientation = UIInterfaceOrientationMaskLandscapeRight;
//強(qiáng)制旋屏
[[UIDevice currentDevice] setValue:@(UIInterfaceOrientationLandscapeRight) forKey:@"orientation"];
[UIViewController attemptRotationToDeviceOrientation];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
((AppDelegate *)[UIApplication sharedApplication].delegate).allowRotate = NO;
//還原豎屏
((AppDelegate *)[UIApplication sharedApplication].delegate).interfaceOrientation = UIInterfaceOrientationMaskPortrait;
//強(qiáng)制旋屏箱吕,還原豎屏
[[UIDevice currentDevice] setValue:@(UIDeviceOrientationPortrait) forKey:@"orientation"];
[UIViewController attemptRotationToDeviceOrientation];
}
其中比較重要的一行
[UIViewController attemptRotationToDeviceOrientation];
當(dāng)你發(fā)生屏幕旋轉(zhuǎn)時(shí)調(diào)用這句代碼芥驳,可以解決一些奇怪的bug,比如橫屏返回后茬高,本應(yīng)豎屏的界面也是橫屏等兆旬。
結(jié)語
在測試當(dāng)中,碰到一些問題:
- 旋屏后的手勢返回問題怎栽,這個(gè)問題可以通過禁用返回手勢解決
- 依然會有push后不橫屏的情況丽猬,但是概率不高,在能接受的范圍熏瞄,具體原因不詳脚祟,若有解決方案的朋友歡迎來交流。