在开发过程中,我们通常会遇到 获取 iPhone 绕自身的旋转角度 以及 获取 iPhone 与水平面的夹角 这类需求。打个比方,在项目中,我们需要集成一个相机拍摄照片的功能。前提条件是让只允许相机在横屏状态下进行拍摄,而竖屏状态下禁止拍摄。如果要实现这个需求,那么仅仅靠系统内置的相机 API 是无法实现的,那么我们就需要自定义相机。而本文就是解决在自定义相机时如何显示手机自身的状态,并拿到这个状态进而决定是否允许拍摄。
如下图,分别是在我自定义相机拍摄时横竖屏的一个界面展示状态,正好描述了上文描述的一个情景:
可以发现,在竖屏状态下时,会有一层灰黑色的蒙版,上面有提醒横屏拍摄的标识语,按钮也是禁用状态,只有退出按钮可用。而在横屏状态下时,拍照按钮可用,提示标语和蒙版均消失。那么,究竟怎么才能实现横竖屏的判定呢?
代码:
//
// 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 绕自身旋转的角度。这样无论你的手机如何倾斜翻转,我们都能拿到它当前的一个状态。多次测试之后,就能获取到你想要设定的一个状态区间了。