我们先简单了解一下,加速计可以用来干嘛。我们下次有时间再继续讲解陀螺仪的使用,以下,我们只能使用真机测试,系统提供的模拟器无法支持这些操作
补充: 简单来说,测试的时候,手机的三维坐标,那个轴的正方向朝下,重力加速度方向就在朝下的那个合力上,这个可能理解就简单了
- 确定设备的朝向
- 确定设备是否在移动
- 检测设备是否倾斜
既然是加速计,那就自然和重力无法脱离关系,iOS系统中提供了这么一套机制,CoreMotion.framework
框架,我们可以以通过加速计来检测摇动手势,目前我知道一些支持摇动频率的SDK基本上都是使用了加速计来做的,我们接下来开始一步步学习如何在应用中获取设备朝向、加速、旋转
的使用,在当前下的设备,基本上都可以以使用加速计检测到运动。
加速计基础
了解:
加速计的度量单位是g ,这个是重力(gravity)的简称。1g 是物体在地球的海平面上受到的下拉力(9.8m/s²)。那么1g 的力到底是多大呢,可以举个简单的例子,我们坐电梯急速下落时(当然很少见)、还有做过山车时您有没有什么感觉呢,为什么在最高处下落您会尖叫呢,这里我们开个玩笑,我们在过山车的移动过程中,在最低处我们的的下拉力是超过1g 的,在最高处,我们是低于1g 所以我们最高处总感觉要飞出来,这就是负重力在起作用。
- 加速计 是以相对于自由落体的方式度量加速度。如果我们将iOS设备从100层大楼自由落体下去,下落过程中,其加速度理想情况应该是0g ,另一方面,放在桌面上的设备,其加速度应该是1g ,且方向朝上
,原理想必都明白吧。 - 假如设备静止是受到的地球牵引力为1g ,这是加速度用于确定设备朝向的基础,加速计可以同时测量3个轴的值(x、y、z),通过感知特定方向的惯性总量,加速计可以测量出加速度和重力,iPhone的加速计是一个三轴加速计 这意味着我们使用iOS可以检测到三维空间中德运动或者重力引力。因此,加速计不但可以检测握持电话的方式(自动旋转功能),而且如果电话放在桌子上的话,还可以指示电话的正面朝下还是朝上,加速计可以测量g引力.
如果加速计返回值为1.0时,表示在特定方向上感知到1g
如果是静止握持iPhone手机没有任何运动,那么地球引力对其施加的力大约为1g
如果是纵向垂直握持iPhone,那么iPhone会检测并报告其Y轴上施加的力大约为1g
如果是以一定角度握持iPhone手机,那么1g 的力会均匀的分布到不同的轴上,这个取决于iPhone的握持方式
如果以45°角握持时,1g 的力会均匀的分解到两个轴上
下面我们看下坐标系,和iOS内部坐标系一致
整体来说还算清晰的对吧,我们就是根据这么一套逻辑来处理加速计的不同方向的分量的。
注意点: 如果我们检测到的加速计大于1g ,那么可以判断这是突然运动,正常使用时,加速计在任何一轴的都不会检测到大于1g 的值,如果摇动、坠落、投掷iPhone,那么加速计便会在一个或者多个轴上检测到很大的力,iPhone的加速计使用的是三轴结构:垂直于屏幕正面的是z轴,从屏幕上方到home键称为y轴,x轴,根据图片,我们也猜测到是宽度向右为正,加速计对y轴使用了更标准的惯例,既 y轴伸长表示向上的力,与Quart2D的坐标系相反,如果使用Quart2D作为控制机制,那么柏旭要转换y轴坐标
使用OpenGL ES则不需要转换。
下面我们开始进入正轨,iOS中德加速计类 UIAccelerometer 是一个单利模式类, 可以通过方法 sharedAccelerometer
获取其唯一的实例。
加速计需要设置如下两点:
- 设置其代理,用以获取加速计信息的方法
- 设置加速计获取信息的频率。最高支持每秒100次。
接下来我们新建工程,真机测试一下:
NS_CLASS_DEPRECATED_IOS(2_0, 5_0, "UIAccelerometer has been replaced by the CoreMotion framework") __TVOS_PROHIBITED
主意这个类的使用截止系统支持到iOS5 系统,系统已经明确告诉我们,后续使用CoreMotion
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
/**
* 获取到加速计的单利对象
*/
UIAccelerometer * accelertometer = [UIAccelerometer sharedAccelerometer];
/**
* 设置加速计的代理
*/
accelertometer.delegate = self;
/**
* updateInterval 刷新频率,一秒更新30次
*/
accelertometer.updateInterval = 1.0/1.0;
UIButton * button =({
UIButton * btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setTitle:@"我是加速计" forState:UIControlStateNormal];
btn.backgroundColor = [UIColor blueColor];
[self.view addSubview:btn];
btn.frame = CGRectMake(10, 20, 100, 50);
btn;
});
self.btn = button;
}
我们只要遵循其代理方法就可以使用真机进行检测了,这个我们今天就说这么多,下次我们再继续
#pragma mark --UIAccelerometerDelegate
static NSInteger shakeCount = 0;
static NSDate * shakeStart;
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration{
NSString * strinfo = [NSString stringWithFormat:@"x:%g \t y:%g \t z :%g",acceleration.x,acceleration.y,acceleration.z];
NSLog(@"str - %@",strinfo);
//检测摇动 1.5 为轻摇 。2.0 为重摇
if (fabs(acceleration.x)>1.8 || abs(acceleration.y>1.8)||abs(acceleration.z>1.8)) {
NSLog(@"你摇动我了");
}
self.btn.frame = CGRectMake(fabsf(acceleration.x) *100, fabsf(acceleration.y) *100, 100, 40);
NSDate * now = [[NSDate alloc]init];
NSDate * checkDate = [[NSDate alloc]initWithTimeInterval:1.5f sinceDate:shakeStart];
if ([now compare:checkDate] ==NSOrderedDescending || shakeStart ==nil) {
shakeStart = [NSDate date];
}
if (fabs(acceleration.x)>1.7 || abs(acceleration.y>1.7)||abs(acceleration.z>1.7)) {
shakeCount++;
if (shakeCount>2) {
NSLog(@"你已经把我摇动了");
shakeCount = 0;
shakeStart = [NSDate date];
}
}
}
通过以上的方法我们可以稍微真机测试一下加速计的摇动频率了,设置我们的摇一摇的频率大小,如有问题,请咨询 QQ群:392633290 备注
只是简单的介绍,会用就行,这个方法也过时了,苹果已经推荐了新的API,我们下次一起研究一下新的API, CoreMotion 框架 ,到底还有多少东西,我们慢慢来学习。
总结:我的iOS开发生涯也不算太久,但是对于技术的钻研,比较喜欢算法,我对OC的整体感觉,只要你懂英文,其实看一下都不是很难,当你把一件事情熟练到自己无法想象的地步,你还能学不会么,古人不是有一句话么,书读百遍,其义自现,这句话我觉得很实在。有不足之处还望大牛看到指点一二,毕竟在某些方面喜欢了解,就会有不周到的地方,可以这么说,是程序就会有BUG,应该可以这么说吧,很多事情都是未知。对未知的事情探索永无止境。