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

在iOS6以前的版本中,一般使用 shouldAutorotateToInterfaceOrientation 來單獨控制某個UIViewController的方向,須要哪一個viewController支持旋轉,只須要重寫shouldAutorotateToInterfaceOrientation方法。html

可是iOS 6裏屏幕旋轉改變了不少,以前的 shouldAutorotateToInterfaceOrientation 被列爲 DEPRECATED 方法,查看UIViewController.h文件也能夠看到:ios

 

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

 

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

 

[cpp]  view plain copy
  1. - (BOOL)shouldAutorotate;  
  2. - (NSUInteger)supportedInterfaceOrientations;  
除了重寫這個2個方法,IOS6裏面要旋轉還有一些須要注意的地方,下面會細述。另外還有一個硬性條件,須要在Info.plist文件裏面添加程序支持的全部方向,能夠經過如下2種方式添加

 

1.ide

 

2.oop

 

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

 

IOS6自動旋轉設置:

IOS6裏面,控制某個viewController旋轉並非像IOS5或者IOS4同樣在這個viewController裏面重寫上面那2個方法,而是須要在這個viewController的rootViewController(根視圖控制器)裏面重寫,怎麼解釋呢?就是最前面的那個viewController,直接跟self.window接觸的那個controller,好比如下代碼:
[cpp]  view plain copy
  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方法,好比:
[cpp]  view plain copy
  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,通常的寫法都是
[cpp]  view plain copy
  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裏面的實現方法改成如下方式:
[cpp]  view plain copy
  1. - (BOOL)shouldAutorotate    
  2. {    
  3.     return self.topViewController.shouldAutorotate; 
  4.    //topViewController爲UINavigationController的屬性
  5. }    
  6.     
  7. - (NSUInteger)supportedInterfaceOrientations    
  8. {    
  9.     return self.topViewController.supportedInterfaceOrientations;    
  10. }  
所有調用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裏面設置
 

IOS五、IOS4自動旋轉設置

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

手動旋轉

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

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

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

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

 

IOS6手動旋轉:

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

[cpp]  view plain copy
  1. - (BOOL)shouldAutorotate{  
  2.         return NO;  
  3. }  
2.手動觸發某個按鈕,調用方法,這個方法的實現以下:
[cpp]  view plain copy
  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的狀況下才管用!

 

IOS五、IOS4手動旋轉:

1.在須要手動旋轉的viewController裏的 shouldAutorotateToInterfaceOrientation 方法設置 interfaceOrientation == [UIApplicationsharedApplication].statusBarOrientation
[cpp]  view plain copy
  1. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{  
  2.     return (interfaceOrientation == [UIApplication sharedApplication].statusBarOrientation);  
  3. }  
2.手動觸發某個按鈕,調用方法,這個方法的實現以下:
[cpp]  view plain copy
  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代替或者直接寫死數字!
[cpp]  view plain copy
  1. -(NSUInteger)supportedInterfaceOrientations{  
  2.     return [UIApplication sharedApplication].statusBarOrientation;  
  3. }  
3.通常都不建議在程序裏面直接調用 UIDeviceOrientation 的方向,而是用 UIInterfaceOrientation,他們之間是不一樣的!
[cpp]  view plain copy
  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
 
轉自:http://blog.csdn.net/zzfsuiye/article/details/8251060#t6
相關文章
相關標籤/搜索