前言
在iOS開發中,有時候需要檢測搖一搖的動作,檢測手機是否進行搖一搖,目前主要有兩種方法,一個是通過UIResponder
中的回撥方法,一個是通過加速計進行計算檢測。前者相較於後者開發簡單,但是有一定的侷限性,如計算搖一搖次數誤差過大。
通過UIResponder
中的回撥方法檢測搖一搖
如果是簡單判斷手機是否有搖一搖的動作可以用UIResponder
中的幾個回撥方法進行捕捉動作:
- (void)motionBegan:(UIEventSubtype)motion withEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(3_0);//搖動開始
- (void)motionEnded:(UIEventSubtype)motion withEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(3_0);
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(3_0);
複製程式碼
注意:在使用這些方法的時候需要判斷一下motion
的型別為搖動的型別,如:
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {
if (UIEventSubtypeMotionShake == motion) {
//搖一搖
}
}
複製程式碼
二、通過加速計檢測搖一搖動作
蘋果提供了CoreMotion
框架讓開發者獲取加速計和陀螺儀資料,這裡主要介紹如何通過加速計檢測搖一搖並計算搖一搖次數。
1、加速計判斷搖一搖的思路
加速計的座標軸如圖,是個三維的座標。
我們需要通過x、y、z三個軸的方向的加速度計算出搖動手機時,手機搖動方向的加速度a。 公式為:
加速計中的單位為:g(重力加速度9.8米/秒)。 接著我們需要設定一個閾值判斷是否算為搖一搖的動作,我這裡設定的是1.6g,(由於有重力,在手機靜止時加速計,依然會有1g的加速度,所以閾值一定要大於1) 當加速度超過1.6g時便可以記錄一次搖動,這裡要新增一個布林值isMoving
來標記該次搖動是否結束,防止一次搖動記錄了多次,但是當低於1.3g後當做這次搖動結束。
2、實現
首先要引入標頭檔案
#import <CoreMotion/CoreMotion.h>
相關實現程式碼如下:
_motionMgr = [[CMMotionManager alloc] init];
__block BOOL isMoving = NO;
__block int count = 0;
[_motionMgr startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAccelerometerData * _Nullable accelerometerData, NSError * _Nullable error) {
CMAcceleration acceleration = accelerometerData.acceleration;
float x = acceleration.x;
float y = acceleration.y;
float z = acceleration.z;
float v = sqrt(x*x + y*y + z*z); //算出實際加速度
if (v > 1.6) {
if (!isMoving) {//次數加1
count++;
}
isMoving = YES;
}else if (v > 1.3){
isMoving = YES;
}else {
isMoving = NO;
}
}];
複製程式碼
本文的方案裡是簡單地通過一個方向的加速度來檢測搖一搖,精確度有限,如果要提升精確度有幾個優化點: 1、通過加速度乘時間獲取位移速度,在本方案的基礎上加上位移的判斷。 2、減去預設存在的重力加速度(我暫時沒找到減去預設存在的重力加速度)。