iOS-屏幕旋轉控制總結

這段時間做的一個app,需求是大部分界面豎屏,播放器頁面橫屏,網頁播放可橫屏可豎屏。查閱了一些資料,也踩了一些坑, 在這里做一個總結。

iOS如何支持旋屏

1. project->target->Deployment Info->Device Orientation


這里的Landscape LeftDevice Orientation,是指內容的方向,即此時手機向右旋轉,home鍵在左邊;而Landscape Right表示手機向右左旋轉,home鍵在右邊

2. 代碼控制

在AppDelegate中添加方法

- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
    return UIInterfaceOrientationMaskAll;
}

當使用代碼控制旋屏方向時,第一點的Device Orientation配置就失效了

關于旋屏之后狀態欄消失的問題,解決辦法是在需要旋屏的UIViewController中重寫3個方法

//設置樣式
- (UIStatusBarStyle)preferredStatusBarStyle {
    return UIStatusBarStyleDefault;
}

//設置是否隱藏
- (BOOL)prefersStatusBarHidden {
    return NO;
}

//設置隱藏動畫
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
    return UIStatusBarAnimationNone;
}

如果不想在ViewController中都去重寫,可以選擇

  1. 繼承一個基類ViewController,在基類中重寫上述3個方法
  2. 新建Category
@implementation UIViewController (StatusBarCategory)

//設置樣式
- (UIStatusBarStyle)preferredStatusBarStyle {
    return UIStatusBarStyleDefault;
}

//設置是否隱藏
- (BOOL)prefersStatusBarHidden {
    return NO;
}

//設置隱藏動畫
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
    return UIStatusBarAnimationNone;
}

@end

如果風格統一,推薦第二種寫法,盡量減少使用繼承;若需要定制狀態欄,可以使用第一種方案

那么現在來說說需要解決旋屏的需求

通常app大部分界面豎屏,有的界面強制橫屏,如播放器,而有的界面支持橫豎屏,如UIWebView

因為所有的旋屏都會走AppDelegate的方法

-(UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window;

所以在AppDelegate.h暴露2個參數

@property (nonatomic, assign) BOOL allowRotate;
@property (nonatomic, assign) UIInterfaceOrientationMask interfaceOrientation;

AppDelegate.m中

//初始化參數
- (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;
    //強制旋屏
    [[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;
    //強制旋屏,還原豎屏
    [[UIDevice currentDevice] setValue:@(UIDeviceOrientationPortrait) forKey:@"orientation"];
    [UIViewController attemptRotationToDeviceOrientation];
}

其中比較重要的一行

 [UIViewController attemptRotationToDeviceOrientation];

當你發生屏幕旋轉時調用這句代碼,可以解決一些奇怪的bug,比如橫屏返回后,本應豎屏的界面也是橫屏等。

結語

在測試當中,碰到一些問題:

  • 旋屏后的手勢返回問題,這個問題可以通過禁用返回手勢解決
  • 依然會有push后不橫屏的情況,但是概率不高,在能接受的范圍,具體原因不詳,若有解決方案的朋友歡迎來交流。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • iOS屏幕旋轉學習筆記iOS開發中使用屏幕旋轉功能的相關方法 1、基本知識點解讀 了解屏幕旋轉首先需要區分兩種 o...
    Laughingg閱讀 13,550評論 13 39
  • 前段時間抽空總結了一下iOS視頻播放的基本用法,發現這其中還有一個我們無法繞過的問題,那就是播放界面的旋轉與適配。...
    梧雨北辰閱讀 31,371評論 14 147
  • [這是第11篇] 導語: iOS App中大多數頁面是只展示豎屏下的效果,但是少部分頁面需要支持橫豎屏。本文分別介...
    南華coder閱讀 14,528評論 18 93
  • 1、UIDeviceOrientation 設備的物理方向 簡介UIDeviceOrientation即我們手持的...
    MrJ的雜貨鋪閱讀 27,874評論 8 75
  • 1. 昨天晚上打車,遇到一個滴滴司機,就跟他聊天,他說已經在北京有兩套房子,三個孩子,兩個已經大學畢業,最小的兒子...
    劉灰灰閱讀 295評論 0 0