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
相关文章
相关标签/搜索