• IOS屏幕旋转思路和实践


      这段时间同事在做一个直播项目,项目有个需求:一个界面需要手动设置屏幕的方向,设置好之后方向不能变化。完成这个需求花了特别大的精力,归因是网上关于屏幕旋转的知识比较凌乱,解决问题花费不少时间,最后决定把这些知识总结哈,以给后面遇到问题的同仁一点参考。

      首先我们来看一些基础知识:

      (一)如何单独的控制某个界面是否可以旋转?

      自IOS6之后,屏幕旋转的方法就变为下面2个方法:

    -(BOOL)shouldAutorotate   //是否允许控制器旋转屏幕
    
    -(UIInterfaceOrientationMask)supportedInterfaceOrientations  //允许的方向有哪些

      理论上来说,我们要控制某个界面是否旋转和其允许的旋转的方向,只需在相应的控制器中实现这两个方法,便能实现我们的需求。但是有2种较特殊情形需要考虑,即控制器被包含在UINavigationController和UITabBarController,这2类控制器为其他控制器提供容器。如果我们需要控制屏幕旋转的某个控制器从属于这2类控制器,则界面方向由UINavigationController和UITabBarController中控制屏幕旋转的两个方法确定。(我是用UINavigationController来实践,如果UITabBarController有差异,可适当调整)。但如果控制器A直接用模态方式推出(presentViewController方式),则我们可以直接在该控制器中实现屏幕旋转方向即可,系统会自动调用控制屏幕旋转的方法。

      有必要对从属这个概念解释下:如果一个控制A从属于UINavigationController B.那么在B的viewControllers属性中则会包含A。一般我们用的pushViewController方式推出控制器A,系统就会将其加入到B的viewControllers。

      对于从属方式的控制器,设置屏幕的自动旋转,我们只需在系统调用UINavigationController的shouldAutorotate或supportedInterfaceOrientations方法的返回值中,主动调用从属控制器的相应方法,将其返回值作为容器类控制器的结果即可,具体操作如下:

    //在UINavigationControllers实现该方法
    - (BOOL)shouldAutorotate    
    {    
        return self.topViewController.shouldAutorotate;    
    }    
    -(UIInterfaceOrientationMask)supportedInterfaceOrientations
    {
        return self.topViewController.supportedInterfaceOrientations;
    
    }
    //然后在从属于UINavigationControllers的控制器中重写上面2个方法即可实现每个界面单独控制屏幕旋转
    

       (二)如何根据某个事件,调整屏幕的方向?

      常用的屏幕旋转方向有2种:一种是改变改变view.transform的属性;另外一种是强制调用屏幕旋转方法。具体可参考下面链接:

                                        http://blog.csdn.net/starryheavens/article/details/8083644

      本文选择第二种——强制屏幕旋转,经证实可行,具体代码如下:

    -(void)setOrientation:(UIInterfaceOrientation) oritation
    {
    
        SEL selector = NSSelectorFromString(@"setOrientation:");
        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice  instanceMethodSignatureForSelector:selector]];
        [invocation setSelector:selector];
        [invocation setTarget:[UIDevice currentDevice]];
        NSInteger val = oritation;
        [invocation setArgument:&val atIndex:2];
        [invocation invoke];
    }
    

      需要强调的是,在调用上面方法设置屏幕旋转方向时,系统会检测该控制器是否允许旋转,即调用shouldAutorotate,如果该方法返回NO,调用上述方法无用。

    
    

       (三)实现最开始需求

      思路:需求中,用户不操作时,则不允许屏幕旋转,因此shouldAutorotate返回值应该是NO,但是触发某个事件,需要将屏幕设置相应的状态时,我们必须在调用setOrientation:方法之前将shouldAutorotate的返回值设置为YES,当调用setOrientation:完毕,我们需要将shouldAutorotate的返回值设置成NO。  

      因此,我们定义一个属性allowRotate来表示是否允许屏幕旋转,具体代码如下: 

    @property (nonatomic,assign) BOOL allowRotate;//是否允许屏幕旋转的变量
    
    -(BOOL)shouldAutorotate
    {
        return _allowRotate;
    }
    
    触发事件
    -(void)screenRotateClick
    {
       
        _allowRotate = YES;
        [self setOrientation:UIInterfaceOrientationPortraitUpsideDown];
        _allowRotate = NO;
    
    }
    

       希望本文写的一些知识能够帮助到你!

     
  • 相关阅读:
    极客mysql01
    Mysql之存储过程与存储函数
    MySQL视图详细介绍
    mysql 触发器的创建和使用
    分治 315. 计算右侧小于当前元素的个数
    128. 最长连续序列
    MySQL慢查询开启、日志分析(转)
    如何在Linux服务器上安装MariaDB或MySQL?
    如何重设MySQL的root密码
    如何修复docker-machine: command not found error
  • 原文地址:https://www.cnblogs.com/shengzaiwen/p/7199425.html
Copyright © 2020-2023  润新知