首页 > 代码库 > IOS Core Motion、UIAccelerometer(加速计使用)

IOS Core Motion、UIAccelerometer(加速计使用)

加速计

 

加速计的作用
用于检测设备的运动(比如摇晃)

加速计的经典应用场景

摇一摇
计步器

 
加速计程序的开发
iOS4以前:使用UIAccelerometer,用法非常简单(到了iOS5就已经过
期)

iOS4开始:CoreMotion.framework

虽然UIAccelerometer已经过期,但由于其用法极其简单,很多程序里面都 还有残留

 

UIAccelerometer的使用步骤
获得单例对象
UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];

 

设置代理 accelerometer.delegate = self;

设置采样间隔
accelerometer.updateInterval = 1.0/30.0; // 1秒钟采样30

实现代理方法
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:

(UIAcceleration *)acceleration
// acceleration中的xyz三个属性分别代表每个轴上的加速度

 

技术分享
#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
View Code

 

 

 

Core Motion(iPhone4)
苹果特地在iOS4中增加了专门处理Motion的框架-CoreMotion.framework

 

Core Motion获取数据的两种方式
push
实时采集所有数据(采集频率高)

pull
在有需要的时候,再主动去采集数据

 

Core Motion的使用步骤(push)

 

创建运动管理者对象
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;


Core Motion的使用步骤(pull)

 创建运动管理者对象

CMMotionManager *mgr = [[CMMotionManager alloc] init];

判断加速计是否可用(最好判断)
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
View Code

 

 

 

IOS Core Motion、UIAccelerometer(加速计使用)