zoukankan      html  css  js  c++  java
  • IOS6屏幕旋转详解(自动旋转、手动旋转、兼容IOS6之前系统)

    来源:http://blog.csdn.net/sakulafly/article/details/18088237

    概述:

    在iOS6之前的版本中,通常使用 shouldAutorotateToInterfaceOrientation 来单独控制某个UIViewController的方向,需要哪个viewController支持旋转,只需要重写shouldAutorotateToInterfaceOrientation方法。

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

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

    程序将使用如下2个方法来代替:

    [cpp] view plaincopy
     
    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,比如以下代码:
    [cpp] view plaincopy
     
    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 plaincopy
     
    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 plaincopy
     
    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 plaincopy
     
    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有被拒的风险:

    [cpp] view plaincopy
     
    1. if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {  
    2.     [[UIDevice currentDevice] performSelector:@selector(setOrientation:) withObject:(id)UIInterfaceOrientationPortrait];  
    3. }  

    第二种是假旋转,并没有改变 UIDevice 的 orientation,而是改变某个view的 transform,利用 CGAffineTransformMakeRotation 来达到目的,比如:

    [cpp] view plaincopy
     
    1. self.view.transform = CGAffineTransformMakeRotation(M_PI/2)  


    下面讲解采用第二种方式的各版本手动旋转:

    思想是首先设置 statusBarOrientation,然后再改变某个view的方向跟 statusBarOrientation 一致!

    IOS6手动旋转:

    1. 那既然是旋转,最少也得有2个方向,那么还是少不了上面说的那个硬性条件,先在plist里面设置好所有可能需要旋转的方向。既然是手动旋转,那么就要关闭自动旋转:

    [cpp] view plaincopy
     
    1. - (BOOL)shouldAutorotate{  
    2.         return NO;  
    3. }  

    2.手动触发某个按钮,调用方法,这个方法的实现如下:

    [cpp] view plaincopy
     
    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

    [cpp] view plaincopy
     
    1. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{  
    2.     return (interfaceOrientation == [UIApplication sharedApplication].statusBarOrientation);  
    3. }  

    2.手动触发某个按钮,调用方法,这个方法的实现如下:

    [cpp] view plaincopy
     
    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 plaincopy
     
    1. -(NSUInteger)supportedInterfaceOrientations{  
    2.     return [UIApplication sharedApplication].statusBarOrientation;  
    3. }  

    3.一般都不建议在程序里面直接调用 UIDeviceOrientation 的方向,而是用 UIInterfaceOrientation,他们之间是不同的!

    [cpp] view plaincopy
     
    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

  • 相关阅读:
    Linux文件属性
    [Oracle] Listener的动态注册
    jQuery easyUI Pagination控件自定义div分页(不用datagrid)
    桂林电子科技大学出校流量控制器Android版1.0.0
    php使用check box
    Python windows ping
    Python selenium chrome 环境配置
    Linux wget auto login and backup database
    PyQt4 ShowHMDB show sqlite3 with QTableWidget summary
    PyQt4 py2exe 打包 HardwareManager
  • 原文地址:https://www.cnblogs.com/sunminmin/p/3795440.html
Copyright © 2011-2022 走看看