標籤:
轉自:
CoreMotion是一個專門處理Motion的架構,其中包含了兩個部分 加速度計和陀螺儀,在iOS4之前加速度計是由 UIAccelerometer 類 來負責採集資料,現在一般都是用CoreMotion來處理加速度過程,不過由於UIAccelerometer比較簡單,同樣有人在使用。加速計由三個 座標軸決定,使用者最常見的操作裝置的動作移動,晃動手機(搖一搖),傾斜手機都可以被裝置檢測到,加速計可以檢測到線性變化,陀螺儀可以更好的檢測到偏 轉的動作,可以根據使用者的動作做出相應的動作,iOS模擬器無法類比以上動作,真機調試需要開發人員帳號。
加速計
加速計的x,y,z三個方向,參考:
如果只需要知道裝置的方向,不需要知道具體方向向量角度,那麼可以使用UIDevice進行操作,還可以根據方向就行判斷,具體可以參考一下蘋果官網代碼:
-(void) viewDidLoad { // Request to turn on accelerometer and begin receiving accelerometer events [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil];}- (void)orientationChanged:(NSNotification *)notification { // Respond to changes in device orientation}-(void) viewDidDisappear { // Request to stop receiving accelerometer events and turn off accelerometer [[NSNotificationCenter defaultCenter] removeObserver:self]; [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];}
當使用者晃動裝置的時候,系統會通知每一個在用的裝置,可以使本身成為第一響應者:
- (BOOL)canBecomeFirstResponder { return YES;} - (void)viewDidAppear:(BOOL)animated { [self becomeFirstResponder];}
處理Motion事件有三種方式,開始(motionBegan),結束(motionEnded),取消(motionCancelled):
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event NS_AVAILABLE_IOS(3_0);- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event NS_AVAILABLE_IOS(3_0);- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event NS_AVAILABLE_IOS(3_0);
motionEnded方法中處理:
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event { if (motion == UIEventSubtypeMotionShake) { // FlyElephant http://www.cnblogs.com/xiaofeixiang [[NSNotificationCenter defaultCenter] postNotificationName:@"FlyElephant" object:self]; }}
CoreMotion在處理加速計資料和陀螺儀資料的時是一個非常重要的架構,架構本身整合了很多演算法擷取原生的資料,而且能很好的展現出 來,CoreMotion與UIKit不同,串連的是UIEvent而不是事件響應鏈。CoreMotion相對於接收資料只是更簡單的分發motion 事件。
CMMotionManager 類能夠使用到裝置的所有移動資料(motion data),Core Motion架構提供了兩種對motion資料的操作方式:
pull方式:能夠以CoreMotionManager的唯讀方式擷取當前任何感應器狀態或是組合資料;
push方式:是以塊或者閉包的形式收集到想要得到的資料並且在特定周期內得到即時的更新;
pull處理方式:
//判斷加速計是否可用 if ([_motionManager isAccelerometerAvailable]) { // 設定加速計採樣頻率 [_motionManager setAccelerometerUpdateInterval:1 / 40.0]; [_motionManager startAccelerometerUpdates]; } else { NSLog(@"部落格園-FlyElephant"); }
觸摸結束:
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{ CMAcceleration acceleration=_motionManager.accelerometerData.acceleration; NSLog(@"%f---%f---%f",acceleration.x,acceleration.y,acceleration.z);}
push處理方式:
@property (strong,nonatomic) CMMotionManager *motionManager;@property (strong,nonatomic) NSOperationQueue *quene;
_motionManager=[[CMMotionManager alloc]init];//判斷加速計是否可用if ([_motionManager isAccelerometerAvailable]) { // 設定加速計頻率 [_motionManager setAccelerometerUpdateInterval:1 / 40.0]; //開始採樣資料 [_motionManager startAccelerometerUpdatesToQueue:_quene withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) { NSLog(@"%f---%f",accelerometerData.acceleration.x,accelerometerData.acceleration.y); }];} else { NSLog(@"部落格園-FlyElephant");}
時間設定頻率:
陀螺儀
陀螺儀其實主要方法和方式和加速計沒有區別,先看張陀螺儀旋轉的角度圖片:
陀螺儀更新資料也有兩種方式,pull方式( startGyroUpdates ),push方式( startGyroUpdatesToQueue ):
static const NSTimeInterval gyroMin = 0.01;- (void)startUpdatesWithSliderValue:(int)sliderValue { // Determine the update interval NSTimeInterval delta = 0.005; NSTimeInterval updateInterval = gyroMin + delta * sliderValue; // Create a CMMotionManager CMMotionManager *mManager = [(APLAppDelegate *)[[UIApplication sharedApplication] delegate] sharedManager]; APLGyroGraphViewController * __weak weakSelf = self; // Check whether the gyroscope is available if ([mManager isGyroAvailable] == YES) { // Assign the update interval to the motion manager [mManager setGyroUpdateInterval:updateInterval]; [mManager startGyroUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMGyroData *gyroData, NSError *error) { [weakSelf.graphView addX:gyroData.rotationRate.x y:gyroData.rotationRate.y z:gyroData.rotationRate.z]; [weakSelf setLabelValueX:gyroData.rotationRate.x y:gyroData.rotationRate.y z:gyroData.rotationRate.z]; }]; } self.updateIntervalLabel.text = [NSString stringWithFormat:@"%f", updateInterval];}- (void)stopUpdates{ CMMotionManager *mManager = [(APLAppDelegate *)[[UIApplication sharedApplication] delegate] sharedManager]; if ([mManager isGyroActive] == YES) { [mManager stopGyroUpdates]; }}
iOS開發-CoreMotion架構