• 谈谈iOS中的屏幕方向


    众所周知,iOS中提供了[UIDevice currentDevice].orientation与[UIApplication sharedApplication].statusBarOrientation这两种方式来获取设备的屏幕方向。

    其中UIDeviceOrientation包括以下几种枚举值

    typedef NS_ENUM(NSInteger, UIDeviceOrientation) {
        UIDeviceOrientationUnknown,
        UIDeviceOrientationPortrait,            // Device oriented vertically, home button on the bottom
        UIDeviceOrientationPortraitUpsideDown,  // Device oriented vertically, home button on the top
        UIDeviceOrientationLandscapeLeft,       // Device oriented horizontally, home button on the right
        UIDeviceOrientationLandscapeRight,      // Device oriented horizontally, home button on the left
        UIDeviceOrientationFaceUp,              // Device oriented flat, face up
        UIDeviceOrientationFaceDown             // Device oriented flat, face down
    } __TVOS_PROHIBITED;

    其中UIInterfaceOrientation包括以下几种枚举值

    typedef NS_ENUM(NSInteger, UIInterfaceOrientation) {
        UIInterfaceOrientationUnknown            = UIDeviceOrientationUnknown,
        UIInterfaceOrientationPortrait           = UIDeviceOrientationPortrait,
        UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
        UIInterfaceOrientationLandscapeLeft      = UIDeviceOrientationLandscapeRight,
        UIInterfaceOrientationLandscapeRight     = UIDeviceOrientationLandscapeLeft
    } __TVOS_PROHIBITED;

    可以看出UIInterfaceOrientation本质其实就是UIDeviceOrientation,但是这不是重点,说说我最近遇到的坑吧。

    首先外部是一个tableview的列表页,cell里面有视频可以播,需求是列表页不需要重力感应,也就说一直保持垂直方向,但是cell中的视频点开后需要全屏,这个视频是要有重力感应的。

    这时会出现一个问题,如果我手机保持横屏,第一次进入视频,视频并不会改变方向,并且UIDeviceOrientation打印出来为UIDeviceOrientationPortrait,因为我在视频的controller里才beginGeneratingDeviceOrientationNotifications,[UIDevice currentDevice].orientation在没有遇到方向改变的时候,他是不会更新状态的!!!所以就造成了与实际方向不符的情况。而父页面,也就是列表页的UIInterfaceOrientation始终垂直,所以[UIApplication sharedApplication].statusBarOrientation也是用不了的,肿么办!!!

    于是乎,别人推荐了CMMotionManager来对方向进行判断,CMMotionManager是从属于Core Motion框架,利用iPhone上的重力加速计芯片来捕捉手机的各种加速值。

    代码如下:

    - (void)initializeMotionManager{
        motionManager = [[CMMotionManager alloc] init];
        motionManager.accelerometerUpdateInterval = .2;
        motionManager.gyroUpdateInterval = .2;
    
        [motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue currentQueue]
                   withHandler:^(CMAccelerometerData  *accelerometerData, NSError *error) {
                          if (!error) {
                                    [self outputAccelertionData:accelerometerData.acceleration];
                          }
                          else{
                                    NSLog(@"%@", error);
                          }
        }];
    }
    - (void)outputAccelertionData:(CMAcceleration)acceleration{
        UIInterfaceOrientation orientationNew;
    
        if (acceleration.x >= 0.75) {
            orientationNew = UIInterfaceOrientationLandscapeLeft;
        }
        else if (acceleration.x <= -0.75) {
            orientationNew = UIInterfaceOrientationLandscapeRight;
        }
        else if (acceleration.y <= -0.75) {
            orientationNew = UIInterfaceOrientationPortrait;
        }
        else if (acceleration.y >= 0.75) {
            orientationNew = UIInterfaceOrientationPortraitUpsideDown;
        }
        else {
            // Consider same as last time
            return;
        }
    
        if (orientationNew == orientationLast)
            return;
    
        orientationLast = orientationNew;
    }

    这样就可以实时的获得当前设备的方向啦

  • 相关阅读:
    [LeetCode] 75. 颜色分类(荷兰国旗)
    [LeetCode] 347. 前K个高频元素
    CMU-14445 数据库原理 汇总
    MIT-6.824 操作系统 汇总
    发布一个基于协程和事件循环的c++网络库
    记录一次gdb debug经历
    彻底弄懂UTF-8、Unicode、宽字符、locale
    CPU使用率原理及计算方式
    TCP使用注意事项总结
    STL-vector
  • 原文地址:https://www.cnblogs.com/jacklandrin/p/4934745.html
Copyright © 2020-2023  润新知