服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - IOS - iOS使用CoreMotion实现摇一摇功能

iOS使用CoreMotion实现摇一摇功能

2021-05-03 16:50宋_波 IOS

这篇文章主要为大家详细介绍了iOS使用CoreMotion实现摇一摇功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

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

 iOS使用CoreMotion实现摇一摇功能

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//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

 iOS使用CoreMotion实现摇一摇功能

第二步,引入头文件

?
1
#import <coremotion/coremotion.h>

第三步,使用cmmotionmanager

?
1
@property (strong,nonatomic) cmmotionmanager *motionmanager;

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

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

?
1
2
self.motionmanager = [[cmmotionmanager alloc] init];//一般在viewdidload中进行
self.motionmanager.accelerometerupdateinterval = .1;//加速仪更新频率,以秒为单位

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
-(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中加入如下监听:

?
1
2
3
4
5
6
7
//viewdidappear中加入
[[nsnotificationcenter defaultcenter] addobserver:self
     selector:@selector(receivenotification:)
     name:uiapplicationdidenterbackgroundnotification object:nil];
[[nsnotificationcenter defaultcenter] addobserver:self
     selector:@selector(receivenotification:)
     name:uiapplicationwillenterforegroundnotification object:nil];
?
1
2
3
4
5
//viewdiddisappear中取消监听
[[nsnotificationcenter defaultcenter] removeobserver:self
     name:uiapplicationdidenterbackgroundnotification object:nil];
[[nsnotificationcenter defaultcenter] removeobserver:self
     name:uiapplicationwillenterforegroundnotification object:nil];
?
1
2
3
4
5
6
7
8
9
10
//对应上面的通知中心回调的消息接收
-(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://blog.csdn.net/u012894479/article/details/48629455

延伸 · 阅读

精彩推荐
  • IOSiOS通过逆向理解Block的内存模型

    iOS通过逆向理解Block的内存模型

    自从对 iOS 的逆向初窥门径后,我也经常通过它来分析一些比较大的应用,参考一下这些应用中某些功能的实现。这个探索的过程乐趣多多,不仅能满足自...

    Swiftyper12832021-03-03
  • IOS解析iOS开发中的FirstResponder第一响应对象

    解析iOS开发中的FirstResponder第一响应对象

    这篇文章主要介绍了解析iOS开发中的FirstResponder第一响应对象,包括View的FirstResponder的释放问题,需要的朋友可以参考下...

    一片枫叶4662020-12-25
  • IOS关于iOS自适应cell行高的那些事儿

    关于iOS自适应cell行高的那些事儿

    这篇文章主要给大家介绍了关于iOS自适应cell行高的那些事儿,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的...

    daisy6092021-05-17
  • IOSiOS中tableview 两级cell的展开与收回的示例代码

    iOS中tableview 两级cell的展开与收回的示例代码

    本篇文章主要介绍了iOS中tableview 两级cell的展开与收回的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    J_Kang3862021-04-22
  • IOSIOS 屏幕适配方案实现缩放window的示例代码

    IOS 屏幕适配方案实现缩放window的示例代码

    这篇文章主要介绍了IOS 屏幕适配方案实现缩放window的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要...

    xiari5772021-06-01
  • IOSiOS 雷达效果实例详解

    iOS 雷达效果实例详解

    这篇文章主要介绍了iOS 雷达效果实例详解的相关资料,需要的朋友可以参考下...

    SimpleWorld11022021-01-28
  • IOSIOS开发之字典转字符串的实例详解

    IOS开发之字典转字符串的实例详解

    这篇文章主要介绍了IOS开发之字典转字符串的实例详解的相关资料,希望通过本文能帮助到大家,让大家掌握这样的方法,需要的朋友可以参考下...

    苦练内功5832021-04-01
  • IOSiOS布局渲染之UIView方法的调用时机详解

    iOS布局渲染之UIView方法的调用时机详解

    在你刚开始开发 iOS 应用时,最难避免或者是调试的就是和布局相关的问题,下面这篇文章主要给大家介绍了关于iOS布局渲染之UIView方法调用时机的相关资料...

    windtersharp7642021-05-04