首页 > 代码库 > IOS Core Motion、UIAccelerometer(加速计使用)
IOS Core Motion、UIAccelerometer(加速计使用)
● 用于检测设备的运动(比如摇晃)
● 加速计的经典应用场景
● 摇一摇
● 计步器
● 在iOS4以前:使用UIAccelerometer,用法非常简单(到了iOS5就已经过期)
● 从iOS4开始:CoreMotion.framework
● 虽然UIAccelerometer已经过期,但由于其用法极其简单,很多程序里面都 还有残留
UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];
● 设置代理 accelerometer.delegate = self;
● 设置采样间隔
accelerometer.updateInterval = 1.0/30.0; // 1秒钟采样30次
● 实现代理方法
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:
(UIAcceleration *)acceleration
// acceleration中的x、y、z三个属性分别代表每个轴上的加速度
#import "ViewController.h" #import "UIView+Extension.h" @interface ViewController ()<UIAccelerometerDelegate> /** * 小球 */ @property (weak, nonatomic) IBOutlet UIImageView *imageBall; /** * 保存速度 */ @property (nonatomic, assign) CGPoint velocity; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // 1.利用单利获取采集对象 UIAccelerometer *acc = [UIAccelerometer sharedAccelerometer]; // 2.设置代理 acc.delegate = self; // 3.设置采样时间 acc.updateInterval = 1 / 30; } #pragma mark -UIAccelerometerDelegate // 4.实现代理方法 /** * 只要采集到数据就会调用(调用频率非常高) * * @param accelerometer 触发事件的对象 * @param acceleration 获取到得数据 */ - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration { NSLog(@"x = %f / y = %f / z = %f", acceleration.x, acceleration.y, acceleration.z); /* 速度 = 加速度 * 时间 V = at; == a * t1 + a * t2 + a * t3 ....; */ // 不能直接修改对象的结构体属性的成员 // self.velocity.x += acceleration.x; _velocity.x += acceleration.x; // -=的原因是因为获取到得Y轴的加速度和UIKit的坐标系的Y的值是相反的, 而我们将来想让小球往加速度的反方向运动, 所以 -=; _velocity.y -= acceleration.y; /* 移动的距离 = 速度 * 时间 S = vt; == v * t1 + v * t2 + v * t3 ....; */ self.imageBall.x += _velocity.x; self.imageBall.y += _velocity.y; // 边界检测 if (self.imageBall.x <= 0) { // 矫正小球当前的位置 self.imageBall.x = 0; // 超出了屏幕的左边 _velocity.x *= -0.5; } if (self.imageBall.y <= 0) { // 矫正小球当前的位置 self.imageBall.y = 0; // 超出屏幕的顶部 _velocity.y *= -0.5; } if (CGRectGetMaxY(self.imageBall.frame) >= self.view.height) { // 矫正小球当前的位置 self.imageBall.y = self.view.height - self.imageBall.height; // 查出屏幕的底部 _velocity.y *= -0.5; } if (CGRectGetMaxX(self.imageBall.frame) >= self.view.width) { // 矫正小球当前的位置 self.imageBall.x = self.view.width - self.imageBall.width; // 查出屏幕的右边 _velocity.x *= -0.5; } } @end
● 实时采集所有数据(采集频率高)
● pull
● 在有需要的时候,再主动去采集数据
CMMotionManager *mgr = [[CMMotionManager alloc] init];
● 判断加速计是否可用(最好判断)
if (mgr.isAccelerometerAvailable) {
// 加速计可用 }
● 设置采样间隔
mgr.accelerometerUpdateInterval = 1.0/30.0; // 1秒钟采样30次
● 开始采样(采样到数据就会调用handler,handler会在queue中执行)
- (void)startAccelerometerUpdatesToQueue:(NSOperationQueue *)queue
withHandler:(CMAccelerometerHandler)handler;
● 创建运动管理者对象
● 判断加速计是否可用(最好判断)
if (mgr.isAccelerometerAvailable) { // 加速计可用 }
● 开始采样
- (void)startAccelerometerUpdates;
● 在需要的时候采集加速度数据
CMAcceleration acc = mgr.accelerometerData.acceleration;
NSLog(@"%f, %f, %f", acc.x, acc.y, acc.z);
#import "ViewController.h" #import <CoreMotion/CoreMotion.h> @interface ViewController () @property (nonatomic, strong) CMMotionManager *mgr; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // 1.创建coreMotion管理者 self.mgr = [[CMMotionManager alloc] init]; if (self.mgr.isAccelerometerAvailable) { // 3.开始采样 [self.mgr startAccelerometerUpdates]; // pull }else { NSLog(@"加速计不可用"); } } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { CMAcceleration acceleration = self.mgr.accelerometerData.acceleration; NSLog(@"x = %f y = %f z = %f", acceleration.x, acceleration.y , acceleration.z); } - (void)push { // 1.创建coreMotion管理者 // CMMotionManager *mgr = [[CMMotionManager alloc] init]; self.mgr = [[CMMotionManager alloc] init]; // 2.判断加速计是否可用 if (self.mgr.isAccelerometerAvailable) { /* isAccelerometerActive 是否正在采集 accelerometerData 采集到得数据 startAccelerometerUpdates pull startAccelerometerUpdatesToQueue push stopAccelerometerUpdates 停止采集 accelerometerUpdateInterval 采样时间 */ // 3.设置采样时间 self.mgr.accelerometerUpdateInterval = 1 / 30.0; // 4.开始采样 [self.mgr startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) { // 这个block是采集到数据时就会调用 if (error) return ; CMAcceleration acceleration = accelerometerData.acceleration; NSLog(@"x = %f y = %f z = %f", acceleration.x, acceleration.y , acceleration.z); }]; }else { NSLog(@"加速计不可用"); } } @end
IOS Core Motion、UIAccelerometer(加速计使用)