• iOS开发-CoreMotion框架


    转自:

     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];
      }
    }
    
  • 相关阅读:
    C# 遍历enum类型元素、获取最大值、最小值
    ABAP-成本报表案例
    recovering corrupted postgres database
    自定义QHeaderView后,点击表头排序失效的解决办法
    Visual Studio 2017社区版登录时始终卡在登录界面的另一个登录办法
    已经安装好的TortoiseSVN在更改盘符后不能使用无法卸载也无法安装的解决办法
    使用别人已经静态编译好的Qt库在进行自己的Qt Creator配置时,在配置Qt Version时出现的2个问题解决办法
    ASCII、Unicode和UTF-8,一文看懂,保存链接
    centos7 挂载硬盘操作
    一次性kill所有进程的命令
  • 原文地址:https://www.cnblogs.com/feiyu-mdm/p/5568475.html
Copyright © 2020-2023  润新知