iOS屏幕轉(zhuǎn)屏實現(xiàn)總結(jié)

在最近的開發(fā)中測試提交了個Bug:"打開視頻播放并將視頻橫屏播放,將App退到后臺凛澎,通過widget入口打開App霹肝,播放的視頻關(guān)閉,結(jié)果App主頁面顯示橫屏",這個問題讓我有看了下iOS設(shè)置轉(zhuǎn)屏的相關(guān)內(nèi)容塑煎,個人覺得有必要總結(jié)下沫换,將結(jié)果落實在筆頭上有助于記憶!

轉(zhuǎn)屏的實現(xiàn)機(jī)制

  • 轉(zhuǎn)屏基礎(chǔ)

加速計是實現(xiàn)iOS轉(zhuǎn)屏的基礎(chǔ)最铁。依賴加速計才可以判斷出設(shè)備當(dāng)前的方向讯赏,通過加速計檢測設(shè)備方向變化,將會發(fā)出UIDeviceOrientationDidChangeNotification這個通知冷尉,通知App設(shè)備方向發(fā)生了變化漱挎,注冊這個通知后在通知對應(yīng)的方法中處理轉(zhuǎn)屏后的UI相關(guān)操作即可。

圖片
  1. 設(shè)備旋轉(zhuǎn)的時候UIKit會受到轉(zhuǎn)屏事件的通知
  2. UIKit通過AppDelegate通知當(dāng)前的Window雀哨,并設(shè)置支持的屏幕方向磕谅;
  3. window通知ViewController的轉(zhuǎn)屏事件私爷,判斷該viewController所支持的旋轉(zhuǎn)方向,完成旋轉(zhuǎn);(如果頁面結(jié)構(gòu)為viewControllerNavigationUITabbarController判斷有差異膊夹,后面會介紹)
  4. 如果存在模態(tài)彈出的viewController的話衬浑,系統(tǒng)則會根據(jù)此ViewController的設(shè)置來判斷是否要進(jìn)行旋轉(zhuǎn);

UIDeviceOrientationDidChangeNotification這個通知是設(shè)備的物理方向發(fā)生變化時會被發(fā)送放刨,有時手機(jī)屏幕頁面沒有變化旋轉(zhuǎn)的需求工秩,但是此通知仍被發(fā)送,所以這時會引起一些問題

  • 加速計判斷屏幕方向
self.motionManager = [[CMMotionManager alloc] init];
if (![self.motionManager isGyroAvailable]) {
  NSLog(@"CMMotionManager 陀螺儀不可用");
}
else{
  // 3.設(shè)置陀螺儀更新頻率进统,以秒為單位
  self.motionManager.gyroUpdateInterval = 0.1;
  // 4.開始實時獲取
  [self.motionManager startGyroUpdatesToQueue:[[NSOperationQueue     alloc] init] withHandler:^(CMGyroData * _Nullable gyroData, NSError * _Nullable error) {
            //獲取陀螺儀數(shù)據(jù)
            CMRotationRate rotationRate = gyroData.rotationRate;
            NSLog(@"CMMotionManager 加速度 == x:%f, y:%f, z:%f", rotationRate.x, rotationRate.y, rotationRate.z);
        }];
   }

轉(zhuǎn)屏相關(guān)枚舉值:

一共有三個枚舉值助币,下面就一一簡單的介紹下

  • UIDeviceOrientation:

UIDeviceOrientation指的是硬件設(shè)備當(dāng)前的旋轉(zhuǎn)方向,判斷設(shè)備方向以Home鍵作為參考麻昼,這個枚舉在UIDevive.h中奠支。

  • 枚舉內(nèi)容
typedef NS_ENUM(NSInteger, UIDeviceOrientation) {
    UIDeviceOrientationUnknown,
    UIDeviceOrientationPortrait,            // Device oriented vertically, home button on the bottom
    UIDeviceOrientationPortraitUpsideDown,  // Device oriented vertically, home button on the top
    UIDeviceOrientationLandscapeLeft,       // Device oriented horizontally, home button on the right
    UIDeviceOrientationLandscapeRight,      // Device oriented horizontally, home button on the left
    UIDeviceOrientationFaceUp,              // Device oriented flat, face up
    UIDeviceOrientationFaceDown             // Device oriented flat, face down
} API_UNAVAILABLE(tvOS);
  • 獲取設(shè)備旋轉(zhuǎn)方向的方法
[UIDevice currentDevice].orientation
  • orientation這個屬性是只讀的馋辈,設(shè)備方向是只能取值抚芦,不能設(shè)置值
@property(nonatomic,readonly) UIDeviceOrientation orientation;
  • 監(jiān)聽設(shè)備方向變化
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleDeviceOrientationChange) name:UIDeviceOrientationDidChangeNotification object:nil];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
- (BOOL)handleDeviceOrientationChange{
    UIDeviceOrientation *deviceOrientation = [UIDevice currentDevice].orientation
    //根據(jù)設(shè)備方向處理不同的情況
    //省略.....
}

APP可以選擇性的是否接收UIDeviceOrientationDidChangeNotification通知。
相關(guān)屬性:

// 是否已經(jīng)開啟了設(shè)備方向改變的通知
@property(nonatomic,readonly,getter=isGeneratingDeviceOrientationNotifications) BOOL generatesDeviceOrientationNotifications;
// 開啟接收接收 UIDeviceOrientationDidChangeNotification 通知
- (void)beginGeneratingDeviceOrientationNotifications;
// 結(jié)束接收接收 UIDeviceOrientationDidChangeNotification 通知
- (void)endGeneratingDeviceOrientationNotifications;
在 app 代理里面結(jié)束接收 設(shè)備旋轉(zhuǎn)的通知事件, 后續(xù)的屏幕旋轉(zhuǎn)監(jiān)聽都會失效
 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // 結(jié)束接收接收 UIDeviceOrientationDidChangeNotification 通知
    [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
    return YES;
}
  • UIInterfaceOrientation 頁面的顯示方向:

UIInterfaceOrientation指的是頁面當(dāng)前旋轉(zhuǎn)的方向迈螟,頁面方向是可以設(shè)置的叉抡,在系統(tǒng)鎖屏按鈕開啟的狀態(tài)下依舊可以通過強制轉(zhuǎn)屏來實現(xiàn)屏幕旋轉(zhuǎn)。這個枚舉值定義在UIApplication.h中答毫。

  • 枚舉類型
typedef NS_ENUM(NSInteger, UIInterfaceOrientation) {
UIInterfaceOrientationUnknown = UIDeviceOrientationUnknow, UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait,
UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight,
UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft
}

通過UIInterfaceOrientationUIDeviceOrientation對比發(fā)現(xiàn)兩者之間大部分的枚舉值是可以對應(yīng)上的褥民,只有以下兩個枚舉值是相反的:

UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight,
UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft

當(dāng)設(shè)備向左轉(zhuǎn)時屏幕是需要向右轉(zhuǎn)的,當(dāng)設(shè)備向右轉(zhuǎn)時屏幕是需要向左轉(zhuǎn)的洗搂;

  • 獲取頁面方向的方式

iOS 8之前

//讀取UIViewController的interfaceOrientation屬性
@property(nonatomic,readonly) UIInterfaceOrientation

iOS 13之前消返,獲取狀態(tài)條方向

[UIApplication sharedApplication].statusBarOrientation

iOS13之后,獲取狀態(tài)條方向

[UIApplication sharedApplication].delegate.window.windowScene.interfaceOrientation;

獲取頁面方向的方法封裝

- (UIInterfaceOrientation)currentInterfaceOrientation
{
    if (@available(iOS 13.0 , *)) {
        return [UIApplication sharedApplication].delegate.window.windowScene.interfaceOrientation;
    }
    return [UIApplication sharedApplication].statusBarOrientation;
}
  • 監(jiān)聽頁面方向變化

在iOS13之前使用一下消息通知Key來注冊監(jiān)聽耘拇,通過監(jiān)聽狀態(tài)條的方向變化來監(jiān)聽頁面方向變化

UIApplicationWillChangeStatusBarOrientationNotification
UIApplicationDidChangeStatusBarOrientationNotification

其他消息通知Key

UIApplicationStatusBarOrientationUserInfoKey
UIApplicationWillChangeStatusBarFrameNotification
UIApplicationDidChangeStatusBarFrameNotification
UIApplicationStatusBarFrameUserInfoKey

在iOS13以后以上的所有key雖然都已經(jīng)DEPRECATED了撵颊,但仍然可以使用,但是蘋果建議使用viewWillTransitionToSize:withTransitionCoordinator:來替代頁面方向變化監(jiān)聽惫叛。

  • UIInterfaceOrientationMask頁面方向

UIInterfaceOrientationMask是iOS6之后增加的一種枚舉倡勇,他是一個為了實現(xiàn)支持多種屏幕方向UIInterfaceOrientation而定義的類型。這個枚舉值也定義在UIApplication.h中嘉涌。

  • 枚舉類型
typedef NS_OPTIONS(NSUInteger,UIInterfaceOrientationMask) {
  UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait),
  UIInterfaceOrientationMaskLandscapeLeft = (1 << UIInterfaceOrientationLandscapeLeft),
  UIInterfaceOrientationMaskLandscapeRight = (1 << UIInterfaceOrientationLandscapeRight),
  UIInterfaceOrientationMaskPortraitUpsideDown = (1 << UIInterfaceOrientationPortraitUpsideDown),
  UIInterfaceOrientationMaskLandscape = (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight),
  UIInterfaceOrientationMaskAll = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortraitUpsideDown),
  UIInterfaceOrientationMaskAllButUpsideDown = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight),
}

轉(zhuǎn)屏相關(guān)方法介紹

  • AppDelegate中的相關(guān)方法
//iOS6在UIApplucationDelegate中提供這個方法妻熊,用于指定UIWindow的界面屏幕方向
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    return UIInterfaceOrientationMaskPortrait;
}
  • 根視圖中的轉(zhuǎn)屏相關(guān)方法

常用方法

方法1:設(shè)置決定當(dāng)前頁面是否可以自動旋轉(zhuǎn),YES為支持旋轉(zhuǎn)仑最,NO為不支持旋轉(zhuǎn)扔役;如果返回NO,則其他轉(zhuǎn)屏相關(guān)方法將不會再被調(diào)用。

- (BOOL)shouldAutorotate

方法2:設(shè)置頁面支持的旋轉(zhuǎn)方向警医。
iPhone上默認(rèn)返回UIInterfaceOrientationMaskAllButUpsideDown亿胸;

iPad上默認(rèn)返回UIInterfaceOrientationMaskAll;

- (UIInterfaceOrientationMask)supportedInterfaceOrientations

方法3:設(shè)置進(jìn)入頁面時默認(rèn)顯示的方向

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentatio

方法4:重寫viewWillTransitionToSize: withTransitionCoordinator:方法來處理旋轉(zhuǎn)后的事件(iOS8之后可以使用此方法,如需要適配iOS8以前的設(shè)備仍需要注冊轉(zhuǎn)屏監(jiān)聽)

-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
    if(size.width > size.height) {
    //橫屏處理
    } else {
    //豎屏處理
    }
}

方法1损敷、2葫笼、3為iOS6以后常用方法,方法4為iOS8以后監(jiān)聽處理轉(zhuǎn)屏完成的方法拗馒;

**其他方法:**
//頁面嘗試旋轉(zhuǎn)到與設(shè)備屏幕方向一致路星,當(dāng)interface orientation和device orientation方向不一致時,希望通過重新指定 interface orientation 的值诱桂,立即實現(xiàn)二者一致
+ (void)attemptRotationToDeviceOrientation
//應(yīng)用將要使用界面支持的方向洋丐,或者將要自動旋轉(zhuǎn) (在iOS6以后被禁用,要兼容iOS 6還是需要實現(xiàn)這個方法)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
//獲取用戶界面的方向 (方法在iOS8被禁用)
@property(nonatomic,readonly) UIInterfaceOrientation interfaceOrientation 
//頁面將要旋轉(zhuǎn)(iOS8以后已經(jīng)失效)
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
//頁面已經(jīng)旋轉(zhuǎn)完成(iOS8以后已經(jīng)失效)
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
//將要動畫旋轉(zhuǎn)到用戶界面(iOS8以后已經(jīng)失效)
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
//界面切換到一半時的回調(diào)(iOS5以后已經(jīng)失效)
- (void)willAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
- (void)didAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
- (void)willAnimateSecondHalfOfRotationFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation duration:(NSTimeInterval)duration

注:再iOS8以后willRotateToInterfaceOrientation和willAnimateRotationToInterfaceOrientation的替代方法為viewWillTransitionToSize:withTransitionCoordinator

  • attemptRotationToDeviceOrientation 使用說明

該方法的使用場景是 interface orientation和device orientation 不一致,但希望通過重新指定 interface orientation 的值挥等,立即實現(xiàn)二者一致友绝;如果這時只是更改了支持的 interface orientation 的值,沒有調(diào)用attemptRotationToDeviceOrientation肝劲,那么下次 device orientation 變化的時候才會實現(xiàn)二者一致迁客,關(guān)鍵點在于能不能立即實現(xiàn)。

假設(shè)當(dāng)前的 interface orientation 只支持 Portrait辞槐。
如果 device orientation 變成 Landscape掷漱,那么 interface orientation 仍然顯示 Portrait;
如果這時我們希望 interface orientation 也變成和 device orientation 一致的 Landscape榄檬,
需要先將 supportedInterfaceOrientations 的返回值改成Landscape卜范,然后調(diào)用 attemptRotationToDeviceOrientation方法,系統(tǒng)會重新詢問支持的 interface orientation鹿榜,已達(dá)到立即更改當(dāng)前 interface orientation的目的

  • 系統(tǒng)版本區(qū)別

iOS 6 and above

iOS6以后再控制器中需要實現(xiàn)的方法

1海雪、shouldAutorotate
2、supportedInterfaceOrientations
3舱殿、preferredInterfaceOrientationForPresentation

iOS5 and before

iOS5之前控制器中需要實現(xiàn)的方法

shouldAutorotateToInterfaceOrientation

決定頁面方向的因素

  • 屏幕旋轉(zhuǎn)控制的優(yōu)先級

Device Orientation控制配置 = AppDelegate中window配置 >根視圖控制器配置 >最上層視圖控制器配置

  • 屏幕旋轉(zhuǎn)控制設(shè)置
  1. Device Orientation方向配置:

在Xcode中依次打開:General→Deployment Info→Device Orientation 設(shè)置支持的旋轉(zhuǎn)方向奥裸,下面的圖片是默認(rèn)設(shè)置。

圖片

注意:如果這四個選項都不選的話怀薛,Device Orientation 的值為默認(rèn)值刺彩。在這里設(shè)置值與 info.plist中設(shè)置的值是同步的,也就是說修改其中的一個枝恋,另一個的值也會相應(yīng)的變化创倔。

  1. Info.plist中方向配置:

上面說了Info.plist中Info.plist中的Supported interface orientation的值與Device Orientation的值是同步的,所以在我們設(shè)置完Device Orientation再到info.plist中查看Supported interface orientation的值焚碌,發(fā)現(xiàn)是一樣的

圖片

注意:在1和2中的設(shè)置都是全局控制的

  1. 在UIApplication中window支持方向設(shè)置:

iOS6的UIApplicationDelegate提供了下述方法畦攘,能夠指定 UIWindow 中的界面的屏幕方向,該方法默認(rèn)值為 Info.plist 中配置的 Supported interface orientations 項的值

//設(shè)置window只支持豎屏
- (NSUInteger)application:(UIApplication *)application  supportedInterfaceOrientationsForWindow:(UIWindow *)window 
{
  return  UIInterfaceOrientationMaskPortrait;
}

window為AppDelegate中所持有的唯一的,并且是全局的十电,所以在方法中設(shè)置的屏幕方向也是全局有效的知押。

  1. 視圖控制器中的方向配置:

在window的根視圖rootViewController和viewController是通過modal模態(tài)彈出方式顯現(xiàn)的時候頁面旋轉(zhuǎn)的相關(guān)方法才會被調(diào)用叹螟,當(dāng)前controller及其所有childViewController都在此作用范圍內(nèi)。如果需求是想控制單個界面支持轉(zhuǎn)屏台盯,就需要在當(dāng)前視圖控制器中重寫以下方法了

//Interface的方向是否會跟隨設(shè)備方向自動旋轉(zhuǎn)罢绽,如果返回NO
- (BOOL)shouldAutorotate {
    return YES;
}
//返回直接支持的方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait;
}
//返回最優(yōu)先顯示的屏幕方向
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationPortrait;
}

這里涉及到的控制器有以下三個:

UITabbarViewController,UINavigationBarController ,UIViewController

當(dāng)頁面嵌套三種控制器使用時静盅,其優(yōu)先級為:

UITabbarViewController>UINavigationBarController >UIViewController

說明:

* 如果是單一的`viewController,`其轉(zhuǎn)屏方向取決于此控制器的轉(zhuǎn)屏方法中的配置良价;
* 如果是`UINavigationBarController + UIViewController`,其轉(zhuǎn)屏方向取決于`UINavigationBarController`導(dǎo)航控制器的轉(zhuǎn)屏方法配置;

如果是UITabbarViewController + UINavigationBarController + UIViewController其轉(zhuǎn)屏方向取決于UIViewController導(dǎo)航控制器的轉(zhuǎn)屏方法配置蒿叠;

總結(jié):

* 如果`viewController`存在根視圖控制器明垢,則`viewController`的轉(zhuǎn)屏相關(guān)方法就不會再被調(diào)用,在`UINavigationBarController + UIViewController`結(jié)構(gòu)下`UINavigationBarController`的方法會被調(diào)用市咽,`UIViewController`的方法失效痊银;在`UITabbarViewController + UINavigationBarController + UIViewController`結(jié)構(gòu)下`UITabbarViewController`的方法會被調(diào)用,其他兩個的方法失效施绎。所以如果期望使用當(dāng)前`viewController`控制器來決定是否轉(zhuǎn)屏就會產(chǎn)生問題(下面會說怎樣由具體VC來控制)溯革,因為這個方法被根視圖控制器攔截了!
  • 如何決定屏幕最終支持的方向

決定界面最后支持的屏幕方向的是 target&plist ∩ AppDeleagte中window設(shè)置 ∩ 視圖控制器設(shè)置 這三個位置的交集粘姜。如果這個交集為空鬓照,就會拋出UIApplicationInvalidInterfaceOrientation異常崩潰。

如何使用具體VC來控制

可以創(chuàng)建UITabbarViewController 孤紧、 UINavigationBarController 、 UIViewController 的子類或分類拒秘,在子類或分類中重寫以下代碼

  • 只存在單獨的viewController時如何設(shè)置
- (BOOL)shouldAutorotate{
    return NO;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAll;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationPortrait;
}
  • 控制器結(jié)構(gòu)為UINavigationController+UIViewController時如何設(shè)置

需要在導(dǎo)航控制器UINavigationController下設(shè)置

//返回導(dǎo)航控制器的頂層視圖控制器的自動旋轉(zhuǎn)屬性号显,因為導(dǎo)航控制器是以棧的原因疊加VC的
-(BOOL)shouldAutorotate{
    return self.topViewController.shouldAutorotate;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return self.topViewController.supportedInterfaceOrientations;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
    return self.topViewController.preferredInterfaceOrientationForPresentation;
}
  • 控制器結(jié)構(gòu)為UITabbarViewController+UINavigationController+UIViewController時如何設(shè)置

需要在UITabbarViewController中設(shè)置

-(BOOL)shouldAutorotate
{
    return self.selectedViewController.shouldAutorotate;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations 
{
    return self.selectedViewController.supportedInterfaceOrientations;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
     return self.selectedViewController.preferredInterfaceOrientationForPresentation;
}
  • 使用模態(tài)視圖

使用模態(tài)modal彈出的viewController不在受到根視圖的控制,具體的設(shè)置和普通視圖器代碼相同躺酒。

強制轉(zhuǎn)屏

  • 方法一

私有方法押蚤,無法直接調(diào)用

[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPortrait]; 

可以間接調(diào)用,上線未被拒

[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIDeviceOrientationUnknown] forKey:@"orientation"];
[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIDeviceOrientationPortrait] forKey:@"orientation"];
 [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIDeviceOrientationUnknown] forKey:@"orientation"];
 [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIDeviceOrientationLandscapeLeft] forKey:@"orientation"];
  • 方法二

也是調(diào)用私有方法,

- (void)setScreenOrientation:(UIInterfaceOrientation)orientation
{
if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
    SEL selector = NSSelectorFromString(@"setOrientation:");
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
    [invocation setSelector:selector];
    [invocation setTarget:[UIDevice currentDevice]];
    int val = orientation;
    [invocation setArgument:&val atIndex:2];  
    [invocation invoke];
    }
}
  • 方法三

旋轉(zhuǎn)view的transform

可以通過旋轉(zhuǎn)view的transform屬性達(dá)到強制旋轉(zhuǎn)屏幕方向的目的,但是這樣會有很多問題羹应,以及適配問題揽碘,AlertView方向,狀態(tài)條方向等园匹。

//設(shè)置statusBar
[[UIApplication sharedApplication] setStatusBarOrientation:orientation];  
//計算旋轉(zhuǎn)角度
float arch;
if (orientation == UIInterfaceOrientationLandscapeLeft)
    arch = -M_PI_2;
else if (orientation == UIInterfaceOrientationLandscapeRight)
    arch = M_PI_2;
else
    arch = 0;
//對根視圖控制器進(jìn)行強制旋轉(zhuǎn)
self.navigationController.view.transform = CGAffineTransformMakeRotation(arch);
self.navigationController.view.bounds = UIInterfaceOrientationIsLandscape(orientation) ? CGRectMake(0, 0, SCREEN_HEIGHT, SCREEN_WIDTH) : initialBounds

注意:

  1. [[UIApplication sharedApplication] setStatusBarOrientation這個方法在iOS9以后已經(jīng)失效雳刺,使用會有警告。如果將shouldAutorotate設(shè)置為YES,setStatusBarOrientation方法設(shè)置無效裸违,只有shouldAutorotate設(shè)置為NO,才會起作用掖桦。

開發(fā)中的問題

  • 在系統(tǒng)鎖屏按鈕開啟,播放器橫屏播放供汛,進(jìn)入后臺枪汪,再回前臺橫屏變豎屏涌穆,需求仍是橫屏

解決:在App從后臺返回前臺后EnterForeground時判斷當(dāng)前頁面方向,如果是橫屏將頁面強制橫屏雀久。

  • 在6p,7p一些支持桌面橫屏的設(shè)備上宿稀,橫屏啟動App頁面橫屏顯示,需求是啟動豎屏

解決:在targe的Device Orientation中只設(shè)置portrait一項

圖片
  • info.plist中設(shè)置Initial interface orientation未起作用

解決:原因未找到

參考文獻(xiàn)

iOS屏幕旋轉(zhuǎn)及其基本適配方法

iOS屏幕旋轉(zhuǎn)問題總結(jié)

IOS Orientation, 想怎么轉(zhuǎn)就怎么轉(zhuǎn)

iOS Rotation

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末赖捌,一起剝皮案震驚了整個濱河市原叮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌巡蘸,老刑警劉巖奋隶,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異悦荒,居然都是意外死亡唯欣,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進(jìn)店門搬味,熙熙樓的掌柜王于貴愁眉苦臉地迎上來境氢,“玉大人,你說我怎么就攤上這事碰纬∑剂模” “怎么了?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵悦析,是天一觀的道長寿桨。 經(jīng)常有香客問我,道長强戴,這世上最難降的妖魔是什么亭螟? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮骑歹,結(jié)果婚禮上预烙,老公的妹妹穿的比我還像新娘。我一直安慰自己道媚,他們只是感情好扁掸,可當(dāng)我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著最域,像睡著了一般谴分。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上羡宙,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天狸剃,我揣著相機(jī)與錄音,去河邊找鬼狗热。 笑死钞馁,一個胖子當(dāng)著我的面吹牛虑省,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播僧凰,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼探颈,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了训措?” 一聲冷哼從身側(cè)響起伪节,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎绩鸣,沒想到半個月后怀大,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡呀闻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年化借,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片捡多。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡蓖康,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出垒手,到底是詐尸還是另有隱情蒜焊,我是刑警寧澤,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布科贬,位于F島的核電站泳梆,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏唆迁。R本人自食惡果不足惜鸭丛,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望唐责。 院中可真熱鬧,春花似錦瘾带、人聲如沸鼠哥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽朴恳。三九已至,卻和暖如春允蚣,著一層夾襖步出監(jiān)牢的瞬間于颖,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工嚷兔, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留森渐,地道東北人做入。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像同衣,于是被迫代替她去往敵國和親竟块。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,573評論 2 353