1. 程式人生 > >IOS Core Motion、UIAccelerometer(加速計使用)

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

就會 property 檢測 isp active 設備 是否 data img

加速計

加速計的作用
用於檢測設備的運動(比如搖晃)

加速計的經典應用場景

搖一搖
計步器

加速計程序的開發
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(加速計使用)