来!我们来玩一下陀螺仪和加速度计

先来看一下效果
111.gif

这是通过调用iOS的陀螺仪和加速度计。通过倾斜手机实现的效果

Core Motion

加速度计和陀螺仪是通过Core Motion框架,来管理访问的。此框架提供了CMMotionManager类,它提供的数据都是用来描述设备的移动的。还提供了CMAccelerometerData和CMGroData,他们可以访问原生的加速度计和陀螺仪信息。另外还有CMDeviceMotion,这个类里面包含有加速度计和陀螺仪的测量数据,以及方位信息。即设备是平放,朝上,朝下,还是朝左等信息。话不多说还是直接上代码。
  先来个坐标系作为参考


屏幕快照 2016-07-09 下午5.24.42.png
看一下各项数据
#define kUpdateInterval (1.f / 60.f)//定义一个更新时间
@property (nonatomic,strong)CMMotionManager *motionManager;
@property (nonatomic,strong)NSOperationQueue *quene;
//声明一个线程

self.motionManager = [[CMMotionManager alloc]init];
    NSOperationQueue *quene = [[NSOperationQueue alloc]init];
初始化一个线程,动作管理器需要一个单独的线程来运行,以便在每次发生事件时放入要执行的工作。苹果文档之处不要放在默认队列,可能会被事件填满,无法处理别的事件

    if (self.motionManager.deviceMotionAvailable) {
        self.motionManager.deviceMotionUpdateInterval = 0.1;
        //设置更新数据的时间间隔
        [self.motionManager startDeviceMotionUpdatesToQueue: quene withHandler:^(CMDeviceMotion * _Nullable motion, NSError * _Nullable error) {
            CMRotationRate rotationRate = motion.rotationRate;
           //旋转速率对应x,y,z分别是设备绕x,y,z 轴(上面有图参考)
           的旋转速率,顺时针为正,逆时针为负
            CMAcceleration gravity = motion.gravity;
            //自然加速度,可是识别手机的放置方向,设备平放在桌上,z=-1;
               屏幕朝左侧立,x = -1;充电口朝下垂直放置,y=-1
            CMAcceleration userAcc = motion.userAcceleration;
            //用户运动手机造成的加速度,分别向xyz方向运动时,正向时即为正值
            CMAttitude *attitude = motion.attitude;
            //设备的旋转程度,也可以理解为设备绕xyz轴旋转的程度,单位是
            弧度,即旋转一周的值为2π,手机绕举个例子:把手机平放在桌面上,
            旋转手机Yaw(偏移)开始变化,旋转180°时yaw = 3.14;
            绕Y轴旋转时Roll变化;绕X轴旋转时Pitch变化(方向不在多做讨论,参考系不一样,没法统一)
            NSString *gyroscopeText = [NSString   stringWithFormat:@"Rotation:\\n x = %.2f\\n y = %.2f\\n 
  z = %.2f",rotationRate.x,rotationRate.y,rotationRate.z];
            NSString *acceleratiorText = [NSString stringWithFormat:@"Accelertion: \\n Gravity x = %.2f\\tUser x = %.2f 
\\n Gravity y = %.2f\\tUser y = %.2f \\n Gravity z = %.2f\\tUser z = %.2f \\n",gravity.x,userAcc.x,gravity.y,userAcc.y,gravity.z,userAcc.z];
            
            NSString *attitudeText = [NSString stringWithFormat:@"Attitute:\\n Roll = %.2f\\nPitch = %.2f
\\nYaw = %.2f\\n",attitude.roll,attitude.pitch,attitude.yaw];
//            NSLog(@"%@",gyroscopeText);
            dispatch_async(dispatch_get_main_queue(), ^{
                _gyroscopeLabel.text = gyroscopeText;
                _accelerometerLabel.text = acceleratiorText;
                _attitudeLabel.text = attitudeText;
            });
        }];
    }

然后我们来做一个Demo

controller中代码实现

#define kUpdateInterval (1.f / 60.f)//更新频率高一点
@interface BallViewController ()
@property (nonatomic,strong)CMMotionManager *motionManager;
@property (nonatomic,strong)NSOperationQueue *quene;
@end
- (void)viewDidLoad {
    [super viewDidLoad];
    BallView *ballView = [[BallView alloc]initWithFrame:self.view.bounds];
//自己写的类继承自UIView
    [self.view addSubview:ballView];
    self.motionManager = [[CMMotionManager alloc]init];
    self.quene = [[NSOperationQueue alloc]init];
    self.motionManager.deviceMotionUpdateInterval = kUpdateInterval;
    [self.motionManager startDeviceMotionUpdatesToQueue:_quene withHandler:^(CMDeviceMotion * _Nullable motion, NSError * _Nullable error) {
//此处也可以传入motion.userAcceleration。(用户移动手机产生的加速度)这样就可以实现摇动来控制(ballView里面的放大倍数记得要改大一点)
        [ballView setAcceleration:motion.gravity];
        dispatch_async(dispatch_get_main_queue(), ^{
        [ballView update];
       //主线程更新UI
        });
    }];
}

BallView的实现
.h文件

#import <UIKit/UIKit.h>
#import <CoreMotion/CoreMotion.h>
@interface BallView : UIView
@property (nonatomic,assign)CMAcceleration acceleration;
- (void)update;
@end

.m文件

@interface BallView ()
@property (nonatomic,assign)CGFloat width;
@property (nonatomic,assign)CGFloat height;
@property (nonatomic,assign)CGFloat imageWidth;
@property (nonatomic,assign)CGFloat imageHeight;
@property (nonatomic,strong)UIImage *image;
@property (nonatomic,strong)UIImageView *imageView;
@property (nonatomic,assign)CGPoint currentPoint;//当前ImageView位置
@property (nonatomic,assign)CGFloat ballXVelocity;//X方向速度
@property (nonatomic,assign)CGFloat ballYVelocity;//Y方向速度
@end

@implementation BallView

- (instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
        [self commoninit];
        self.backgroundColor = [UIColor whiteColor];
    }
    return self;
}
- (void)commoninit{
    self.image = [UIImage imageNamed:@"btn_nav04@3x"];
    self.imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, self.imageWidth, self.imageHeight)];
    self.imageView.image = _image;
    [self addSubview:self.imageView];
    self.currentPoint = CGPointMake(self.bounds.size.width/2.f+self.image.size.width/2.f, self.bounds.size.height/2.f+self.image.size.height/2.f);
    self.imageView.center = _currentPoint;
}

- (void)setCurrentPoint:(CGPoint)newPoint{
    _currentPoint = newPoint;
        //边缘判断
    if (self.currentPoint.x <= self.imageWidth/2.f) {
        _currentPoint.x = self.imageWidth/2.f;
        self.ballXVelocity = -_ballXVelocity/2.f;
        //反弹效果,接触边缘后加速度反向减半
    }
    if (self.currentPoint.y <= self.imageHeight/2.f) {
        _currentPoint.y = self.imageHeight/2.f;
        self.ballYVelocity = -_ballYVelocity/2.f;
        //反弹效果,接触边缘后加速度反向减半
    }
    if (self.currentPoint.x >= self.width -self.imageWidth/2.f ) {
        _currentPoint.x = self.width -self.imageWidth/2.f;
        self.ballXVelocity = -_ballXVelocity/2.f;
        //反弹效果,接触边缘后加速度反向减半
    }
    if (self.currentPoint.y >= self.height -self.imageHeight/2.f ) {
        _currentPoint.y = self.height -self.imageHeight/2.f;
        self.ballYVelocity = -_ballYVelocity/2.f;
       //反弹效果,接触边缘后加速度反向减半
    }
    [self updateCenter];
}
- (void)updateCenter{
    self.imageView.center = _currentPoint;
}

- (void)update{
    static NSDate *lastUpdateTime = nil;
    if (lastUpdateTime != nil) {
        NSTimeInterval secondsSinceLastDraw = [[NSDate date] timeIntervalSinceDate:lastUpdateTime];//两次更新的时间差
        self.ballXVelocity = self.ballXVelocity + (self.acceleration.x * secondsSinceLastDraw);
        //X方向上原速度加上加速度乘以时间,计算当前速度
        self.ballYVelocity = self.ballYVelocity - (self.acceleration.y * secondsSinceLastDraw);
        //Y方向上原速度加上加速度乘以时间,计算当前速度
        CGFloat xAccel = secondsSinceLastDraw * self.ballXVelocity * 1000;
        //计算位置变化量。由于这个值很小,所以我们要放大一些才更加真实此处
        //若想使用摇动,要把放大倍数调大,10000效果不错
        CGFloat yAccel = secondsSinceLastDraw * self.ballYVelocity * 1000;
        self.currentPoint = CGPointMake(self.currentPoint.x + xAccel, self.currentPoint.y + yAccel);
    }
    lastUpdateTime = [NSDate date];
}
#pragma mark - widthAndHeight
- (CGFloat)width{
    return self.bounds.size.width;
}
- (CGFloat)height{
    return self.bounds.size.height;
}
- (CGFloat)imageWidth{
    return self.image.size.width;
}
- (CGFloat)imageHeight{
    return self.image.size.height;
}

这样你就可以实现,倾斜手机来移动图片,就像真是的重力产生的效果一样。同样也可以实现,摇动的效果。(就像安卓的360原来的版本有个摇动的球清理内存那样的效果)。
  如需转载请注明出处,请尊重作者的劳动成果。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容