IOS6屏幕旋轉詳解(自動旋轉、手動旋轉、兼容IOS6之前系統) .

轉自:http://blog.csdn.net/cococoolwhj/article/details/8208991

概述:

在iOS6之前的版本中,通常使用 shouldAutorotateToInterfaceOrientation 來單獨控制某個UIViewController的方向,需要哪個viewController支持旋轉,只需要重寫shouldAutorotateToInterfaceOrientation方法。

但是iOS 6裏屏幕旋轉改變了很多,之前的 shouldAutorotateToInterfaceOrientation 被列爲 DEPRECATED 方法,查看UIViewController.h文件也可以看到:

  1. // Applications should use supportedInterfaceOrientations and/or shouldAutorotate..  
  2. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation NS_DEPRECATED_IOS(2_0, 6_0);  

程序將使用如下2個方法來代替:

  1. - (BOOL)shouldAutorotate;  
  2. - (NSUInteger)supportedInterfaceOrientations;  
除了重寫這個2個方法,IOS6裏面要旋轉還有一些需要注意的地方,下面會細述。另外還有一個硬性條件,需要在Info.plist文件裏面添加程序支持的所有方向,可以通過以下2種方式添加

1.



2.



另外要兼容IOS6之前的系統,要保留原來的 shouldAutorotateToInterfaceOrientation 方法,還有那些 willRotateToInterfaceOrientation 等方法。


IOS6自動旋轉設置:

IOS6裏面,控制某個viewController旋轉並不是像IOS5或者IOS4一樣在這個viewController裏面重寫上面那2個方法,而是需要在這個viewController的rootViewController(根視圖控制器)裏面重寫,怎麼解釋呢?就是最前面的那個viewController,直接跟self.window接觸的那個controller,比如以下代碼:
  1. UIViewController *viewCtrl = [[UIViewController alloc] init];  
  2. UINavigationController *navCtrl = [[UINavigationController alloc] initWithRootViewController:viewCtrl];  
  3. if ([window respondsToSelector:@selector(setRootViewController:)]) {  
  4.     self.window.rootViewController = navCtrl;  
  5. else {  
  6.     [self.window addSubview:navCtrl.view];  
  7. }  
如果需要設置viewCtrl的旋轉,那麼不能在UIViewController裏面重寫shouldAutorotate和supportedInterfaceOrientations方法,而是需要在navCtrl裏面設置,又因爲UINavigationController是系統控件,所以這裏需要新建一個UINavigationController的子navigationController的子類,然後在裏面實現shouldAutorotate和supportedInterfaceOrientations方法,比如:
  1. -(NSUInteger)supportedInterfaceOrientations{  
  2.     return UIInterfaceOrientationMaskAllButUpsideDown;  
  3. }  
  4.   
  5. - (BOOL)shouldAutorotate{  
  6.     return YES;  
  7. }  
eg1:如果上面的例子是self.window.rootViewController = viewCtrl,而不是navCtrl,那麼上面的那2個控制旋轉的方法就應該寫在UIViewController裏面!

eg2:如果viewCtrl又pushViewController到viewCtrl2,需要設置viewCtrl2的旋轉,怎麼辦呢? 還是在navCtrl裏面控制,因爲viewCtrl和viewCtrl2的rootViewController都是navCtrl,一般的寫法都是
  1. UIViewController *viewCtrl2 = [[UIVewController alloc] init];  
  2. [self.navigationController.navigationController pushViewController:viewCtrl2 animated:YES];  
所以要控制一個UINavigationController push到的所有viewController的旋轉,那麼就得在navCtrl裏面區分是哪個viewController,以便對他們一一控制!同樣如果rootViewController是UITabbarController,那麼需要在子類化的UITabbarController裏面重寫那2個方法,然後分別控制!

但是有時候我初始化UINavigationController的時候,並不知道所有我所有需要push到的viewController,那麼這裏有一個通用的方法,就是讓viewController自己來控制自己,首先在navCtrl裏面的實現方法改爲以下方式:
  1. - (BOOL)shouldAutorotate    
  2. {    
  3.     return self.topViewController.shouldAutorotate;    
  4. }    
  5.     
  6. - (NSUInteger)supportedInterfaceOrientations    
  7. {    
  8.     return self.topViewController.supportedInterfaceOrientations;    
  9. }  
全部調用self.topViewController,就是返回當前呈現出來的viewController裏面的設置,然後在viewCtrl、viewCtrl2等等這些viewController裏面重寫shouldAutorotate和supportedInterfaceOrientations,以方便設置每個viewController的旋轉

eg3:如果viewCtrl 是 
presentModalViewController 到 viewCtrl3,那麼viewCtrl3的旋轉設置就不在navCtrl裏面了!如果presentModalViewController的viewController是navController、tabbarController包裝過的viewCtrl3,那麼就應在新包裝的navController、tabbarController裏面設置,如果是直接presentModalViewController到viewCtrl3,那麼就在viewCtrl3裏面設置


IOS5、IOS4自動旋轉設置

這個簡單很多,沒有上面的硬性條件,只需要在需要旋轉的viewController裏面重寫 shouldAutorotateToInterfaceOrientation 方法就行

手動旋轉

手動旋轉也有2種方式,一種是直接設置 UIDevice 的 orientation,但是這種方式不推薦,上傳appStore有被拒的風險:

  1. if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {  
  2.     [[UIDevice currentDevice] performSelector:@selector(setOrientation:) withObject:(id)UIInterfaceOrientationPortrait];  
  3. }  
第二種是假旋轉,並沒有改變 UIDevice 的 orientation,而是改變某個view的 transform,利用 CGAffineTransformMakeRotation 來達到目的,比如:
  1. self.view.transform = CGAffineTransformMakeRotation(M_PI/2)  

下面講解採用第二種方式的各版本手動旋轉:

思想是首先設置 statusBarOrientation,然後再改變某個view的方向跟 statusBarOrientation 一致!


IOS6手動旋轉:

1. 那既然是旋轉,最少也得有2個方向,那麼還是少不了上面說的那個硬性條件,先在plist裏面設置好所有可能需要旋轉的方向。既然是手動旋轉,那麼就要關閉自動旋轉:

  1. - (BOOL)shouldAutorotate{  
  2.         return NO;  
  3. }  
2.手動觸發某個按鈕,調用方法,這個方法的實現如下:
  1. [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];  
  2. self.view.transform = CGAffineTransformMakeRotation(M_PI/2);  
  3. 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裏的 shouldAutorotateToInterfaceOrientation 方法設置 interfaceOrientation == [UIApplicationsharedApplication].statusBarOrientation
  1. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{  
  2.     return (interfaceOrientation == [UIApplication sharedApplication].statusBarOrientation);  
  3. }  
2.手動觸發某個按鈕,調用方法,這個方法的實現如下:
  1. [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];  
  2. self.view.transform = CGAffineTransformMakeRotation(M_PI/2);  
  3. self.view.bounds = CGRectMake(0, 0, kScreenHeight, 320);  
注意:只需要改變self.view.transform,那麼self.view的所有subview都會跟着自動變;其次因爲方向變了,所以self.view的大小需要重新設置,不要使用self.view.frame,而是用bounds。


經驗分享:

1.IOS6裏面,如果一個項目裏面需要各種旋轉支持,有自動,有手動,那麼我們可以新建2個navController或者tabbarController的子類,一個是不旋轉,一個旋轉,那麼所有需要旋轉的UINavigationController都可以用這個子類來代替!包括我們可以定製短信呀、郵件呀的旋轉!
2.supportedInterfaceOrientations 方法一般是寫UIInterfaceOrientationMask方向,但是如果程序要兼容4.3以下的SDK(4.3以下的SDK必須是4.5以下的Xcode,不支持IOS6),那麼在用4.5以下的Xcode編譯的時候通不過!所以可以用statusBarOrientation代替或者直接寫死數字!
  1. -(NSUInteger)supportedInterfaceOrientations{  
  2.     return [UIApplication sharedApplication].statusBarOrientation;  
  3. }  
3.一般都不建議在程序裏面直接調用 UIDeviceOrientation 的方向,而是用 UIInterfaceOrientation,他們之間是不同的!
  1. UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight,  
  2. UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft  
看到嗎,左右是反的!Xcode圖形化設置方向也是以 UIInterfaceOrientation 爲準,就是home按鍵所在的方向

參考:
http://blog.csdn.net/totogogo/article/details/8002173
http://stackoverflow.com/questions/13200220/how-to-change-keyboard-orientation-in-ios6
http://blog.csdn.net/yiyaaixuexi/article/details/8035014
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章