iOS使用CoreMotion实现摇一摇功能

来源:互联网 发布:道路交通事故数据统计 编辑:程序博客网 时间:2024/05/22 04:27

  现在网上介绍的iOS摇一摇功能,基本是以借助系统的ShakeToEdit功能来实现,什么是ShakeToEdit?看下图应该就能懂:


  怎么实现?请看以下代码:

//ViewController 加入以下两方法-(BOOL)canBecomeFirstResponder{//让当前controller可以成为firstResponder,这很重要    return YES;}-(void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event{    if (event.subtype==UIEventSubtypeMotionShake) {        //做你想做的事    }}//在viewDidView中调用以下消息,主动让当前controller成为firstResponder[self becomeFirstResponder];//已经不需要其它多余代码了

  这个方法最简单,但这个功能有时候会失效。它失效的时候,系统所有摇一摇撤销重做都会不起作用,从而导致包括所有关联的Shake事件也不起作用。失效原因或在什么情况下失效,目前还没有相关资料。据这两天个人观察,大多发生在手机放在裤袋中走10多分钟路之后(iPhone5S iOS 7.05).是否因为摇得太久了,系统为了省电就关闭此功能呢?希望大家也拿自己手机来试一试,我们一起来看看这到底是什么问题。

  要恢复,最直接的是连接iTunes,否则,就要让手机平放一段时间,但时候平放一天都没有恢复。所以说此方式不太稳定,微信及其它有摇一摇功能的应用,他们的摇一摇并不受此影响,而且微信的摇一摇动作比ShakeToEdit要轻,可以讲手动动一下就激活了。于是我认为,这些应用都放弃了ShakeToEdit,使用了加速仪,自己重新实现。

  使用加速仪与使用相机,声音之类不同,不需要经过用户允许,也没有访问限制,当然也没什么危害,是个基本配备。那要怎么做?下面费话不多说,直接开始吧:


  第一步,为项目TARGET添加CoreMotion.framework



  第二步,引入头文件

#import <CoreMotion/CoreMotion.h>


  第三步,使用CMMotionManager

@property (strong,nonatomic) CMMotionManager *motionManager;

  注意,当前应用只能有一个CMMotionManager实例,多个实例会影响接收速率


  第四步,实例并初始化加速仪

    self.motionManager = [[CMMotionManager alloc] init];//一般在viewDidLoad中进行    self.motionManager.accelerometerUpdateInterval = .1;//加速仪更新频率,以秒为单位


  第五步,开始接收加速仪数据(startAccelerometerUpdatesToQueue:withHandler:)

-(void)viewDidAppear:(BOOL)animated{    [self startAccelerometer];}-(void)startAccelerometer{    //以push的方式更新并在block中接收加速度    [self.motionManager startAccelerometerUpdatesToQueue:[[NSOperationQueue alloc]init]         withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {        [self outputAccelertionData:accelerometerData.acceleration];        if (error) {            NSLog(@"motion error:%@",error);        }    }];}-(void)outputAccelertionData:(CMAcceleration)acceleration{    //综合3个方向的加速度    double accelerameter =sqrt( pow( acceleration.x , 2 ) + pow( acceleration.y , 2 )         + pow( acceleration.z , 2) );    //当综合加速度大于2.3时,就激活效果(此数值根据需求可以调整,数据越小,用户摇动的动作就越小,越容易激活,反之加大难度,但不容易误触发)    if (accelerameter>2.3f) {  //立即停止更新加速仪(很重要!)        [self.motionManager stopAccelerometerUpdates];                dispatch_async(dispatch_get_main_queue(), ^{            //UI线程必须在此block内执行,例如摇一摇动画、UIAlertView之类        });    }    }-(void)viewDidDisappear:(BOOL)animated{    //停止加速仪更新(很重要!)    [self.motionManager stopAccelerometerUpdates];}

  最后一步

  至此,摇一摇核心已经实现,但还差最后一步:当App退到后台时必须停止加速仪更新,回到当前时重新执行。否则应用在退到后台依然会接收加速度更新,可能会与其它当前应用冲突,产生不好的体验。所以,分别在viewDidAppear和viewDidDisappear中加入如下监听:

    //viewDidAppear中加入    [[NSNotificationCenter defaultCenter] addObserver:self              selector:@selector(receiveNotification:)              name:UIApplicationDidEnterBackgroundNotification object:nil];    [[NSNotificationCenter defaultCenter] addObserver:self              selector:@selector(receiveNotification:)              name:UIApplicationWillEnterForegroundNotification object:nil];
    //viewDidDisappear中取消监听    [[NSNotificationCenter defaultCenter] removeObserver:self              name:UIApplicationDidEnterBackgroundNotification object:nil];    [[NSNotificationCenter defaultCenter] removeObserver:self              name:UIApplicationWillEnterForegroundNotification object:nil];
//对应上面的通知中心回调的消息接收-(void)receiveNotification:(NSNotification *)notification{    if ([notification.name         isEqualToString:UIApplicationDidEnterBackgroundNotification])    {        [self.motionManager stopAccelerometerUpdates];    }else{        [self startAccelerometer]; }}

  至此,所有使用加速仪实现摇一摇功能的实现方式已介绍完毕。

  一些可改进的地方:

  1) 摇一摇动作捕捉——如果仅是以加速度大小来判定,有可能用户突然快速移动手机时就激活了摇动,但用户比较稍稍慢一些来回晃动手机却不会激活,可能与用户期望的稍微有出入。系统的ShakeToEdit就能做得比较到位。
   我们可以结合定时器与加速度的正反方向来更精确判定用户的摇一摇动作,例如:综合加速度改为带方向的向量,然后当1.5秒内有相反两个方向大于某个数值的加速度,才算为一个摇动行为。这个1.5秒时间需要通过实际测试来取值,当某次取得的加速度值大于某个值开始统计下一个加速度向量,此值也需要实测来取值,可能1.5左右就够了。

  2) App状态更改——如果激活的摇一摇是个长时间等待行为,例如弹出ActionSheet让用户选择操作。在用户进行下一步操作前,ActionSheet没消失前,不应该启动下一次监听,包括应用从后台回到当前状态后,也要判断用户是否有过下一步行为。

参考文献:
https://developer.apple.com/library/ios/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/motion_event_basics/motion_event_basics.html#//apple_ref/doc/uid/TP40009541-CH6-SW1

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 前扣内衣扣子坏了怎么办 运动内衣穿上平胸怎么办 文胸的海绵变形了怎么办 文胸背部松紧变形了怎么办 黑色裤子被漂白水漂红了怎么办 黑色裤子晒红了怎么办 黑色裤子泛红了怎么办 黑色裤子洗红了怎么办 新内衣穿了痒怎么办 灰色针织运动裤洗完发黄怎么办 皮衣买大了一号怎么办 紧身衣破了一个洞怎么办 紧身衣破了一个小洞怎么办 内衣肩带不带调整的怎么办 不正确佩戴胸罩导致下垂怎么办 增肌时期晚上饿怎么办 啤酒和可乐喝了怎么办 脸部毛孔堵塞不出汗怎么办 减肥运动完饿了怎么办 想减肥晚上饿了怎么办 孕妇喝不进去水怎么办 跑步喝多了水怎么办 衣柜门轮子坏了怎么办 穿瑜伽裤下边有缝怎么办 3岁宝宝比较内向怎么办 我想和我同学搞基怎么办 自己做的葡萄酒太甜怎么办 吉米学校想退款怎么办 汽车租赁公司不退押金怎么办 身材不好怎么办健身教练形象照 反祈祷式做不到怎么办 窦性心跳过缓怎么办 四维彩超查出胎儿心脏有问题怎么办 减脂肚子饿了怎么办 做瑜伽腰扭到了怎么办 出了汗怎么办活动反思 农村都是老人和孩子怎么办 瑜伽垫容易出现痕迹怎么办 37岁失业了该怎么办 45岁找什么工作怎么办 华为手机4g网速慢怎么办