OC - 屏幕旋轉(自動旋轉、手動旋轉、兼容iOS6之前系統)

導讀:

一、iOS6之前屏幕旋轉知識了解

  1. 直接在需要旋轉的UIViewController重寫控制旋轉的方法就可以了。
 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
     return ((toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) | (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft));
}
  • 此方法默認只支持豎屏向上,上面的例子中,表示支持橫屏向右及橫屏向左兩個方向。
  • 此方法在iOS6之后被列為DEPRECATED 方法。

二、iOS6(包括iOS6)之后屏幕旋轉知識了解

  1. 無論怎么旋轉,先要設置移動設備支持的旋轉方向,兩種方法,在target -> general或target -> info中設置如下,兩種方法選一個就可以(另一個會自動變化)。


  2. UIDeviceOrientation和UIInterfaceOrientation是不同的。
    UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight,
    UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft
  3. UIInterfaceOrientation用來取界面方向,UIInterfaceOrientationMask用來設置界面方向。
  4. iOS6之后,控制某個viewcontroller旋轉的方法需要在這個viewController的rootViewController(根視圖控制器)里面重寫。
  5. iOS6之后使用這3個方法控制屏幕旋轉,一般情況下實現前兩個方法即可。
  • //是否自動旋轉,返回YES可以自動旋轉
    - (BOOL)shouldAutorotate NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED;
    //返回支持的方向
    - (UIInterfaceOrientationMask)supportedInterfaceOrientations NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED;
    // Returns interface orientation masks.
    //這個是返回優先方向
    - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED;
    

三、自動旋轉具體操作

(一) iOS6之后的自動旋轉
  1. 如果UIViewController是根控制器,那么控制testVC10旋轉的兩個方法在testVC10中重寫。
   UIViewController *testVC10 = [[UIViewController alloc] init]; 
  self.window.rootViewController = testVC10;
  - (BOOL)shouldAutorotate{
       return NO;
  }
  #if __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_9_0
  - (NSUInteger)supportedInterfaceOrientations
  #else
  - (UIInterfaceOrientationMask)supportedInterfaceOrientations
  #endif
  {
      return UIInterfaceOrientationMask...;
  }
  1. 如果testVC10再present出一個testVC11,那么控制testVC11旋轉的兩個方法是在testVC11中重寫。
  2. 如果UINavigationController是根控制器,那么可以新建一個UINavigationController的子類,控制testVC20旋轉的兩個方法在這個子類導航控制器中重寫。
 MTViewController *testVC20 = [[MTViewController alloc] init];
 MTNavigationController *nav = [[MTNavigationController alloc] initWithRootViewController:testVC20];
 self.window.rootViewController = nav;
  1. 如果testVC20再push出一個testVC21,那么控制testVC21旋轉的兩個方法也是寫在這個子類導航控制器中。

所以一個UINavigationController要控制push的所有viewController的旋轉,那么就得在nav里面區分是哪個viewController,以便對他們一一控制!同樣如果rootViewController是UITabbarController,那么需要在子類化的UITabbarController里面重寫那2個方法,然后分別控制!
但是有時候初始化UINavigationController的時候,并不知道所有需要push到的viewController,那么這里有一個通用的方法,就是讓viewController自己來控制自己,首先在nav里面的實現方法改為以下方式:

   -(BOOL)shouldAutorotate
   {
      return [self.topViewController shouldAutorotate];
      //或return [[self.viewControllers lastObject] shouldAutorotate];   
   }
  #if __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_9_0
  - (NSUInteger)supportedInterfaceOrientations
  #else
 - (UIInterfaceOrientationMask)supportedInterfaceOrientations
  #endif
  {
       return [self.topViewController supportedInterfaceOrientations];
       //或return [[self.viewControllers lastObject] supportedInterfaceOrientations];
      }

全部調用self.topViewController,就是返回當前呈現出來的viewController里面的設置。然后在testVC20、testVC21等等這些viewController里面重寫shouldAutorotate和supportedInterfaceOrientations就可以了。這樣就可實現單獨控制某個viewController的旋轉了。

  1. 如果testVC10再present到testVC13,且testVC13是用UINavigationController或??UITabBarController包裝過的,那么控制testVC13旋轉的兩個方法在包裝tesVC13的控制器中重寫。
  2. 如果UITabBarController是根控制器,方法如同UINavigationController。
(二) iOS5、iOS4自動旋轉設置簡單很多,沒有上面的硬性條件,只需要在需要旋轉的viewController里面重寫 shouldAutorotateToInterfaceOrientation 方法就行。
  •  - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { return ;}
    

四、手動旋轉具體操作

(一) 手動旋轉
  1. 手動旋轉也有2種方式,一種是直接設置 UIDevice 的 orientation,但是這種方式不推薦,上傳appStore有被拒的風險:
  if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) 
{  
   [[UIDevice currentDevice] performSelector:@selector(setOrientation:) withObject:(id)UIInterfaceOrientationPortrait];  
 } 
  • 第二種是假旋轉,并沒有改變 UIDevice 的 orientation,而是改變某個view的 transform,利用 CGAffineTransformMakeRotation 來達到目的,比如:
    self.view.transform = CGAffineTransformMakeRotation(M_PI/2)

下面講解采用第二種方式的各版本手動旋轉:思想是首先設置 statusBarOrientation,然后再改變某個view的方向跟 statusBarOrientation 一致!

(二) iOS6之后的手動旋轉
  1. 既然是旋轉,最少也得有2個方向,那么還是少不了上面說的那個硬性條件,先在plist里面設置好所有可能需要旋轉的方向。既然是手動旋轉,那么就要關閉自動旋轉:
    - (BOOL)shouldAutorotate{
    return NO;
    }

2.手動觸發某個按鈕,調用方法,這個方法的實現如下:

[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];  
self.view.transform = CGAffineTransformMakeRotation(M_PI/2);  
self.view.bounds = CGRectMake(0, 0, kScreenHeight, 320); 

注意:1. 只需要改變self.view.transform,那么self.view的所有subview都會跟著自動變;其次因為方向變了,所以self.view的大小需要重新設置,不要使用self.view.frame,而是用bounds。2. 如果shouldAutorotate 返回YES的話,下面設置setStatusBarOrientation 是不管用的!setStatusBarOrientation只有在shouldAutorotate 返回NO的情況下才管用!

(三) iOS5、iOS4手動旋轉:
  1. 在需要手動旋轉的viewController里的
    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
    return (interfaceOrientation == [UIApplication sharedApplication].statusBarOrientation);
    }
  2. 手動觸發某個按鈕,調用方法,這個方法的實現如下
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];  
self.view.transform = CGAffineTransformMakeRotation(M_PI/2);  
self.view.bounds = CGRectMake(0, 0, kScreenHeight, 320);

注意:只需要改變self.view.transform,那么self.view的所有subview都會跟著自動變;其次因為方向變了,所以self.view的大小需要重新設置,不要使用self.view.frame,而是用bounds。

五、總結

  • IOS6里面,如果一個項目里面需要各種旋轉支持,有自動,有手動,那么我們可以新建2個navController或者tabbarController的子類,一個是不旋轉,一個旋轉,那么所有需要旋轉的UINavigationController都可以用這個子類來代替!
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,797評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,179評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,628評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,642評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,444評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,948評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,040評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,185評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,717評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,602評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,794評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,045評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,418評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,414評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,750評論 2 370

推薦閱讀更多精彩內容