iOS 【陀螺仪 自身旋转角&水平面夹角 问题】

在开发过程中,我们通常会遇到 获取 iPhone 绕自身的旋转角度 以及 获取 iPhone 与水平面的夹角 这类需求。打个比方,在项目中,我们需要集成一个相机拍摄照片的功能。前提条件是让只允许相机在横屏状态下进行拍摄,而竖屏状态下禁止拍摄。如果要实现这个需求,那么仅仅靠系统内置的相机 API 是无法实现的,那么我们就需要自定义相机。而本文就是解决在自定义相机时如何显示手机自身的状态,并拿到这个状态进而决定是否允许拍摄。

如下图,分别是在我自定义相机拍摄时横竖屏的一个界面展示状态,正好描述了上文描述的一个情景:

《iOS 【陀螺仪 自身旋转角&水平面夹角 问题】》

《iOS 【陀螺仪 自身旋转角&水平面夹角 问题】》

可以发现,在竖屏状态下时,会有一层灰黑色的蒙版,上面有提醒横屏拍摄的标识语,按钮也是禁用状态,只有退出按钮可用。而在横屏状态下时,拍照按钮可用,提示标语和蒙版均消失。那么,究竟怎么才能实现横竖屏的判定呢?

代码:

//
//  PushViewController.m
//  陀螺仪
//
//  Created by CoderZYWang on 2016/12/26.
//  Copyright © 2016年 CoderZYWang. All rights reserved.
//

#import "PushViewController.h"

#import <CoreMotion/CoreMotion.h>

@interface PushViewController ()

@property (nonatomic, strong) CMMotionManager *motionManager;

@end

@implementation PushViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    // 当前的view必须设置背景色,不然根本没法触发屏幕的点击事件
    self.view.backgroundColor = [UIColor whiteColor];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self useGyroPush]; // 界面点击时就会调用陀螺仪
}

- (void)viewDidDisappear:(BOOL)animated {
    // 该界面消失时一定要停止,不然会一直调用消耗内存
    [self.motionManager stopDeviceMotionUpdates]; // 停止所有的设备
//    [self.motionManager stopAccelerometerUpdates]; // 加速度计
//    [self.motionManager stopMagnetometerUpdates]; // 磁力计
//    [self.motionManager stopGyroUpdates]; // 陀螺
}

- (void)useGyroPush{
    //初始化全局管理对象
    CMMotionManager *manager = [[CMMotionManager alloc] init];
    self.motionManager = manager;
    
    if ([self.motionManager isDeviceMotionAvailable]) {
        manager.deviceMotionUpdateInterval = 1;
        [self.motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue]
                                                withHandler:^(CMDeviceMotion * _Nullable motion,
                                                              NSError * _Nullable error) {
            
            // Gravity 获取手机的重力值在各个方向上的分量,根据这个就可以获得手机的空间位置,倾斜角度等
            double gravityX = motion.gravity.x;
            double gravityY = motion.gravity.y;
            double gravityZ = motion.gravity.z;
            
            // 获取手机的倾斜角度(zTheta是手机与水平面的夹角, xyTheta是手机绕自身旋转的角度):
            double zTheta = atan2(gravityZ,sqrtf(gravityX * gravityX + gravityY * gravityY)) / M_PI * 180.0;
            double xyTheta = atan2(gravityX, gravityY) / M_PI * 180.0;
            
            NSLog(@"手机与水平面的夹角 --- %.4f, 手机绕自身旋转的角度为 --- %.4f", zTheta, xyTheta);
        }];
    }
}

@end

通过我们上面 block 回调的结果,我们可以精确的定位 iPhone 与水平面的夹角 以及 iPhone 绕自身旋转的角度。这样无论你的手机如何倾斜翻转,我们都能拿到它当前的一个状态。多次测试之后,就能获取到你想要设定的一个状态区间了。

    原文作者:王中尧
    原文地址: https://blog.csdn.net/Felicity294250051/article/details/53894862
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞