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中的x、y、z三個屬性分別代表每個軸上的加速度
#import "ViewController.h" #import "UIView+Extension.hView Code" @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
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(@"加速計不可用"); } } @endView Code
IOS Core Motion、UIAccelerometer(加速計使用)