加速计

● 加速计的作用
● 用于检测设备的运动(比如摇晃)

● 加速计的经典应用场景

● 摇一摇
● 计步器

● 加速计程序的开发
● 在iOS4以前:使用UIAccelerometer,用法非常简单(到了iOS5就已经过期)

● 从iOS4开始:CoreMotion.framework

● 虽然UIAccelerometer已经过期,但由于其用法极其简单,很多程序里面都
还有残留

UIAccelerometer的使用步骤
● 获得单例对象
UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];

● 设置代理
accelerometer.delegate = self;

● 设置采样间隔
accelerometer.updateInterval = 1.0/30.0; // 1秒钟采样30次

● 实现代理方法
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:

(UIAcceleration *)acceleration
// acceleration中的x、y、z三个属性分别代表每个轴上的加速度

#import "ViewController.h"
#import "UIView+Extension.h" @interface ViewController ()<UIAccelerometerDelegate>
/**
* 小球
*/
@property (weak, nonatomic) IBOutlet UIImageView *imageBall;
/**
* 保存速度
*/
@property (nonatomic, assign) CGPoint velocity;
@end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib. // 1.利用单利获取采集对象
UIAccelerometer *acc = [UIAccelerometer sharedAccelerometer];
// 2.设置代理
acc.delegate = self;
// 3.设置采样时间
acc.updateInterval = / ; }
#pragma mark -UIAccelerometerDelegate
// 4.实现代理方法
/**
* 只要采集到数据就会调用(调用频率非常高)
*
* @param accelerometer 触发事件的对象
* @param acceleration 获取到得数据
*/
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
NSLog(@"x = %f / y = %f / z = %f", acceleration.x, acceleration.y, acceleration.z); /*
速度 = 加速度 * 时间
V = at; == a * t1 + a * t2 + a * t3 ....;
*/
// 不能直接修改对象的结构体属性的成员
// self.velocity.x += acceleration.x;
_velocity.x += acceleration.x;
// -=的原因是因为获取到得Y轴的加速度和UIKit的坐标系的Y的值是相反的, 而我们将来想让小球往加速度的反方向运动, 所以 -=;
_velocity.y -= acceleration.y; /* 移动的距离 = 速度 * 时间
S = vt; == v * t1 + v * t2 + v * t3 ....;
*/
self.imageBall.x += _velocity.x;
self.imageBall.y += _velocity.y; // 边界检测
if (self.imageBall.x <= ) {
// 矫正小球当前的位置
self.imageBall.x = ;
// 超出了屏幕的左边
_velocity.x *= -0.5;
}
if (self.imageBall.y <= ) {
// 矫正小球当前的位置
self.imageBall.y = ;
// 超出屏幕的顶部
_velocity.y *= -0.5;
} if (CGRectGetMaxY(self.imageBall.frame) >= self.view.height) {
// 矫正小球当前的位置
self.imageBall.y = self.view.height - self.imageBall.height;
// 查出屏幕的底部
_velocity.y *= -0.5;
} if (CGRectGetMaxX(self.imageBall.frame) >= self.view.width) {
// 矫正小球当前的位置
self.imageBall.x = self.view.width - self.imageBall.width;
// 查出屏幕的右边
_velocity.x *= -0.5;
} }
@end
/*
> 加速计
*PPT介绍加速计, 加速计属于传感器的范畴...
*新建项目讲解加速计的传统使用
*查看Accelerometer头文件, 讲解Accelerometer头文件中的属性引出为什么过时了还那么多人用(简单, 查看头文件)
*从代理方法参数引出定义属性保存小球加速度(CGPoint), 并在代理方法中设置小球的位置
*Vt = V0 + a * t (最终速度 = 初始速度 + 加速度 * 时间)
Vt = V0 + g * t (加速度是恒定的9.8)
Vt = V0 + g1 + g2 + g3 … (时间和加速度都是恒定的)
Vt = V0 + a1 + a2 + a3 … (手机中时间是恒定的, 加速度不是恒定的)
*从小球移除频幕看不到引出画图讲解边界检测(碰撞检测)
*从小球会贴在边框出不来引出画图讲解如何解决(移动小球的位置到边界再加速度)
*讲解为什么用两个if 不用else if, 小球在四个角的情况
*/ #import "CZViewController.h" @interface CZViewController ()<UIAccelerometerDelegate>
/**
* 小球
*/
@property (nonatomic, weak)UIImageView *ballIv;
/**
* 保存x y方向加速度
*/
@property (nonatomic, assign)CGPoint ballVelocity; @end @implementation CZViewController - (void)viewDidLoad
{
[super viewDidLoad]; // 1.添加小球
UIImage *image = [UIImage imageNamed:@"black"];
UIImageView *iv = [[UIImageView alloc] initWithImage:image];
[self.view addSubview:iv];
self.ballIv = iv; // 2.获得加速计单例
/**
updateInterval 更新间隔(采样,采集数据样本)
delegate 代理
*/
UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];
// 设置采样时间
accelerometer.updateInterval = / 30.0;
// 设置代理
accelerometer.delegate = self;
} #pragma mark - UIAccelerometerDelegate
// UIAcceleration 加速度
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
// 1. 记录小球加速度
_ballVelocity.x += acceleration.x;
// 加速计y轴方向和UIKit坐标相反
_ballVelocity.y -= acceleration.y; // 2.更新小球位置
[self updateLocation];
} - (void)updateLocation
{
// 设置小球的位置
CGPoint center = self.ballIv.center;
CGSize size = self.view.bounds.size; // 解决小球出界问题,碰撞检测
// 水平方向:左边,右边
if (CGRectGetMinX(self.ballIv.frame) <= || CGRectGetMaxX(self.ballIv.frame) >= size.width) {
// 修改小球的速度方向
_ballVelocity.x *= -; // 修复位置 < 0
if (CGRectGetMinX(self.ballIv.frame) <= ) {
center.x = self.ballIv.bounds.size.width / 2.0;
} else {
center.x = size.width - self.ballIv.bounds.size.width / 2.0;
}
} // 垂直方向
if (CGRectGetMinY(self.ballIv.frame) <= || CGRectGetMaxY(self.ballIv.frame) >= size.height) {
// 修改小球的速度方向
_ballVelocity.y *= -; // 修复位置 < 0
if (CGRectGetMinY(self.ballIv.frame) <= ) {
center.y = self.ballIv.bounds.size.height / 2.0;
} else {
center.y = size.height - self.ballIv.bounds.size.height / 2.0;
}
} center.x += _ballVelocity.x;
center.y += _ballVelocity.y; self.ballIv.center = center;
} @end
Core Motion(iPhone4)

苹果特地在iOS4中增加了专门处理Motion的框架-CoreMotion.framework

Core Motion获取数据的两种方式

● push
● 实时采集所有数据(采集频率高)

● pull
● 在有需要的时候,再主动去采集数据

Core Motion的使用步骤(push)

● 创建运动管理者对象
CMMotionManager *mgr = [[CMMotionManager alloc] init];

● 判断加速计是否可用(最好判断)
if (mgr.isAccelerometerAvailable) {

// 加速计可用
}

● 设置采样间隔
mgr.accelerometerUpdateInterval = 1.0/30.0; // 1秒钟采样30次

● 开始采样(采样到数据就会调用handler,handler会在queue中执行)
- (void)startAccelerometerUpdatesToQueue:(NSOperationQueue *)queue

withHandler:(CMAccelerometerHandler)handler;
Core Motion的使用步骤(pull)

● 创建运动管理者对象

CMMotionManager *mgr = [[CMMotionManager alloc] init];

● 判断加速计是否可用(最好判断)
if (mgr.isAccelerometerAvailable) { // 加速计可用 }

● 开始采样
- (void)startAccelerometerUpdates;

● 在需要的时候采集加速度数据
CMAcceleration acc = mgr.accelerometerData.acceleration;
NSLog(@"%f, %f, %f", acc.x, acc.y, acc.z);

实例1:
#import "ViewController.h"
#import <CoreMotion/CoreMotion.h> @interface ViewController ()
@property (nonatomic, strong) CMMotionManager *mgr;
@end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; // 1.创建coreMotion管理者
self.mgr = [[CMMotionManager alloc] init]; if (self.mgr.isAccelerometerAvailable) {
// 3.开始采样
[self.mgr startAccelerometerUpdates]; // pull
}else
{
NSLog(@"加速计不可用");
} } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CMAcceleration acceleration = self.mgr.accelerometerData.acceleration; NSLog(@"x = %f y = %f z = %f", acceleration.x, acceleration.y , acceleration.z);
} - (void)push
{
// 1.创建coreMotion管理者
// CMMotionManager *mgr = [[CMMotionManager alloc] init];
self.mgr = [[CMMotionManager alloc] init]; // 2.判断加速计是否可用
if (self.mgr.isAccelerometerAvailable) {
/*
isAccelerometerActive 是否正在采集
accelerometerData 采集到得数据
startAccelerometerUpdates pull
startAccelerometerUpdatesToQueue push
stopAccelerometerUpdates 停止采集
accelerometerUpdateInterval 采样时间
*/
// 3.设置采样时间
self.mgr.accelerometerUpdateInterval = / 30.0;
// 4.开始采样 [self.mgr startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {
// 这个block是采集到数据时就会调用
if (error) return ;
CMAcceleration acceleration = accelerometerData.acceleration;
NSLog(@"x = %f y = %f z = %f", acceleration.x, acceleration.y , acceleration.z);
}];
}else
{
NSLog(@"加速计不可用");
}
} @end

实例2:

#import "HMViewController.h"
#import <CoreMotion/CoreMotion.h> @interface HMViewController ()
@property (nonatomic, strong) CMMotionManager *mgr;
@end @implementation HMViewController - (void)viewDidLoad
{
[super viewDidLoad]; // 1.创建motion管理者
self.mgr = [[CMMotionManager alloc] init]; // 2.判断加速计是否可用
if (self.mgr.isAccelerometerAvailable) {
[self pull];
} else {
NSLog(@"---加速计不可用-----");
}
}
/**
* ******* pull *******
*/
- (void)pull
{
[self.mgr startAccelerometerUpdates];
} - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CMAcceleration acceleration = self.mgr.accelerometerData.acceleration;
NSLog(@"%f %f %f", acceleration.x, acceleration.y, acceleration.z);
} /**
* ******* push *******
*/
- (void)push
{
// 3.设置采样间隔
self.mgr.accelerometerUpdateInterval = / 30.0; // 4.开始采样(采集加速度数据)
[self.mgr startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {
// 如果在block中执行较好时的操作,queue最好不是主队列
// 如果在block中要刷新UI界面,queue最好是主队列
NSLog(@"%f %f %f", accelerometerData.acceleration.x, accelerometerData.acceleration.y, accelerometerData.acceleration.z);
}];
} @end

实例3:

#import "CZMotionManager.h"

/**
1. 静态的全局实例
2. allocWithZone
3. 定义一个shared方法,供全局使用
*/ // 保存当前类的实例
static CZMotionManager *_instance; @implementation CZMotionManager + (instancetype)shareMotionManager
{
if (_instance == nil) {
_instance = [[[self class] alloc] init];
}
return _instance;
} #pragma mark - 以下方法是为了保证对象在任何情况下都唯一
// 调用alloc的时候会调用这个方法
+ (id)allocWithZone:(struct _NSZone *)zone
{
static dispatch_once_t onceToken;
// 保证我们的block只能执行一次
dispatch_once(&onceToken, ^{
_instance = [super allocWithZone:zone];
});
return _instance;
}
//会在调用copy的时候调用这个方法
- (id)copyWithZone:(NSZone *)zone
{
return self;
} //在调用mutableCopy的时候调用这个方法
- (id)mutableCopyWithZone:(NSZone *)zone
{
return self;
} @end
/*
>PPT讲解CoreMontion
*新建工程导入CoreMontion框架, 拷贝常规使用添加小球代码
*导入CoreMontion框架主头文件, 查看头文件讲解相关属性含义
*实例化运动管理器,—>判断加速计是否可用—>设置采样数据的时间间隔—>开始采样数据 —>更改小球位置
*从运行没有反应引出CoreMontionManage是局部变量
*新建队列替换主队列, 从运行程序没有任何反应引出修改更新方法在主队列中修改UI
*从系统提供的CoreMontionManage不是单例,引出定义子类实现单例(讲解如何实现单例)
*画图讲解从采样时间和刷帧时间不一样小球现实会不清晰引出采样和刷帧单独进行
*从加速计常用于游戏引出实现点击频幕后暂停游戏, 注意不需要每次都销毁CADisplayLink
*/ #import "CZViewController.h"
#import <CoreMotion/CoreMotion.h>
#import "CZMotionManager.h" @interface CZViewController ()
/**
* 小球
*/
@property (nonatomic, weak)UIImageView *ballIv;
/**
* 保存x y方向加速度
*/
@property (nonatomic, assign)CGPoint ballVelocity; /**
* 运动管理器
*/
@property (nonatomic, strong)CMMotionManager *motionM; @property (nonatomic, strong)NSOperationQueue *queue; @property (nonatomic, strong)CADisplayLink *link; @end @implementation CZViewController /**
运动管理器的属性 1> accelerometerUpdateInterval 加速计更新间隔
2> isAccelerometerAvailable 是否可用
3> accelerometerActive 是否正在采集数据
4> accelerometerData 加速计数据(通过Pull方式获得)
5> startAccelerometerUpdatesToQueue 开始加速计更新(通过Push方式实时获得采样数据)
6> stopAccelerometerUpdates 停止数据采样 */
- (void)viewDidLoad
{
[super viewDidLoad];
// 1.添加小球
UIImage *image = [UIImage imageNamed:@"black"];
UIImageView *iv = [[UIImageView alloc] initWithImage:image];
[self.view addSubview:iv];
self.ballIv = iv; self.queue = [[NSOperationQueue alloc] init]; // 2.实例化运动管理器
// CMMotionManager *montionM = [[CMMotionManager alloc] init]; // self.motionM = [[CMMotionManager alloc] init];
self.motionM = [CZMotionManager shareMotionManager]; // 3.判断加速计是否可用
if (self.motionM.isAccelerometerAvailable) {
// 3.1设置采样时间间隔
self.motionM.accelerometerUpdateInterval = / 30.0;
/*
// 3.2 开始采样数据
// [self.motionM startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAccelerometerData * [self.motionM startAccelerometerUpdatesToQueue:self.queue withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) { // NSLog(@"%@", [NSThread currentThread]); // 处理采样数据,修改小球速度
_ballVelocity.x += accelerometerData.acceleration.x;
_ballVelocity.y -= accelerometerData.acceleration.y; // 更改小球位置
// [self updateLocation];
}];
*/
// 3.2 开始采样数据
[self startAccelerometerUpdates];
}else
{
NSLog(@"摔坏了");
} // 4.实例化CADisplayLink
/*
在真机实际运行中,小球的显示并是不非常的清晰,会有一些发虚。
*/
CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateLocation)];
[link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
self.link = link;
}
#pragma mark - 私有方法
#pragma mark 开始采样数据
- (void)startAccelerometerUpdates
{
// 3.2 开始采样数据
[self.motionM startAccelerometerUpdatesToQueue:self.queue withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {
// 处理采样数据,修改小球速度
_ballVelocity.x += accelerometerData.acceleration.x;
_ballVelocity.y -= accelerometerData.acceleration.y; }];
} - (void)updateLocation
{
// 设置小球的位置
CGPoint center = self.ballIv.center;
CGSize size = self.view.bounds.size; // 解决小球出界问题,碰撞检测
// 水平方向:左边,右边
if (CGRectGetMinX(self.ballIv.frame) <= || CGRectGetMaxX(self.ballIv.frame) >= size.width) {
// 修改小球的速度方向
_ballVelocity.x *= -; // 修复位置 < 0
if (CGRectGetMinX(self.ballIv.frame) <= ) {
center.x = self.ballIv.bounds.size.width / 2.0;
} else {
center.x = size.width - self.ballIv.bounds.size.width / 2.0;
}
} // 垂直方向
if (CGRectGetMinY(self.ballIv.frame) <= || CGRectGetMaxY(self.ballIv.frame) >= size.height) {
// 修改小球的速度方向
_ballVelocity.y *= -; // 修复位置 < 0
if (CGRectGetMinY(self.ballIv.frame) <= ) {
center.y = self.ballIv.bounds.size.height / 2.0;
} else {
center.y = size.height - self.ballIv.bounds.size.height / 2.0;
}
} center.x += _ballVelocity.x;
center.y += _ballVelocity.y; // NSLog(@"%@", [NSThread currentThread]); // 在主线程队列上更新小球位置
[[NSOperationQueue mainQueue] addOperationWithBlock:^{ self.ballIv.center = center;
}]; } // 游戏“暂停”——用户点击屏幕,暂停小球运动
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{ if (self.motionM.isAccelerometerActive) {
// 停止
[self.motionM stopAccelerometerUpdates]; /*
invalidate停止时钟
1> 将时钟从主运行循环中撤销
2> 将时钟销毁
[_gameTimer invalidate];
*/ // 直接从主运行循环中将游戏时钟删除,而不会销毁时钟,等到需要时再次添加即可。
[self.link removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}else
{
// 开始采样数据
[self startAccelerometerUpdates]; // 开启时钟
[self.link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}
}
@end

IOS Core Motion、UIAccelerometer(加速计使用)的更多相关文章

  1. IOS 特定于设备的开发:Core Motion基础

    Core Motion框架集中了运动数据处理.该框架是在IOS 4 SDK中引入的,用于取代accelerometer加速计访问.它提供了对3个关键的机载传感器的集中式监测.这些传感器有陀螺仪.磁力计 ...

  2. iOS开发 传感器(加速计、摇一摇、计步器)

    一.传感器 1.什么是传感器传感器是一种感应\检测周围环境的一种装置, 目前已经广泛应用于智能手机上 传感器的作用用于感应\检测设备周边的信息不同类型的传感器, 检测的信息也不一样 iPhone中的下 ...

  3. iOS开发-CoreMotion框架(加速计和陀螺仪)

    CoreMotion是一个专门处理Motion的框架,其中包含了两个部分加速度计和陀螺仪,在iOS4之前加速度计是由UIAccelerometer类来负责采集数据,现在一般都是用CoreMotion来 ...

  4. 转 iOS Core Animation 动画 入门学习(一)基础

    iOS Core Animation 动画 入门学习(一)基础 reference:https://developer.apple.com/library/ios/documentation/Coco ...

  5. iOS - Core Animation 核心动画

    1.UIView 动画 具体讲解见 iOS - UIView 动画 2.UIImageView 动画 具体讲解见 iOS - UIImageView 动画 3.CADisplayLink 定时器 具体 ...

  6. IOS Core Image之二

    在上篇博客IOS Core Image之一中了解了下CIImage.CIFilter.CIContext三个类的使用,这篇了解下滤镜链(多滤镜)和人脸检测(不是人脸识别). 一.多滤镜 1.有些效果不 ...

  7. iOS Core ML与Vision初识

    代码地址如下:http://www.demodashi.com/demo/11715.html 教之道 贵以专 昔孟母 择邻处 子不学 断机杼 随着苹果新品iPhone x的发布,正式版iOS 11也 ...

  8. iOS Core Animation 简明系列教程

    iOS Core Animation 简明系列教程  看到无数的CA教程,都非常的难懂,各种事务各种图层关系看的人头大.自己就想用通俗的语言翻译给大家听,尽可能准确表达,如果哪里有问题,请您指出我会尽 ...

  9. IOS Core Animation Advanced Techniques的学习笔记(一)

    转载. Book Description Publication Date: August 12, 2013 Core Animation is the technology underlying A ...

随机推荐

  1. centos 7 ssh登录安全问题

    2018-10-11 1.ssh禁止root远程登录 修改ssh配置文件/etc/ssh/sshd_config vim /etc/ssh/sshd_config PermitRootLogin ye ...

  2. RNN(recurrent neural network)学习笔记

    参考:https://www.jianshu.com/p/9dc9f41f0b29  以及<白话深度学习与TensorFlow> 与前馈神经网络.卷积神经网络等不同之处在于,RNN具有一定 ...

  3. 超文本传送协议 HTTP

    超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议.所有的WWW文件都必须遵守这个标准. HTTP是一个属于应用层的面向对象的协议, ...

  4. Angular4+NodeJs+MySQL 入门-02 MySql操作类

    NodeJs操作MySQL类 此类封装了几个常用的方法:插入,更新,删除,查询,开启事务,事务提交,事务回滚等操作.有一这个类,操作MYSQL就方便多了. 批处理,存储过程等方法还没有添加,因为觉得目 ...

  5. Ubuntu(Linux) 下 zip 命令使用详解

    1.功能作用:压缩文件或者目录 2.位置:/usr/bin/zip 3.格式用法:zip [-options] [-b path] [-t mmddyyyy] [-n suffixes] [zipfi ...

  6. 搭架Ubuntu的 apt-cacher服务

    源服务器名称可能不太准确,意思是创建内网自己的私服,这样只要有Ubuntu通过该私服下载安装过软件,私服都会缓存,下一个Ubuntu的请求就直接从缓存中获取. 最近Ubuntu源服务器太慢了,北京的网 ...

  7. jquery返回顶部和底部插件和解决ie6下fixed插件

    (function($){ //返回顶部和底部插件 $.fn.extend({ goTopBootom:function (options){ //默认参数 var defaults = { &quo ...

  8. Coursera 机器学习 第9章(上) Anomaly Detection 学习笔记

    9 Anomaly Detection9.1 Density Estimation9.1.1 Problem Motivation异常检测(Density Estimation)是机器学习常见的应用, ...

  9. 腾讯毛华:智能交互,AI助力下的新生态

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 演讲人:毛华 腾讯云语音云总经理 背景:5月23-24日,以"焕启"为主题的腾讯"云+未来"峰会在广 ...

  10. asp ajax

    //[AjaxPro.AjaxMethod()] //public DataTable loadChecked() //{ // return BDAContext.GetObject<ICNP ...