如何实现mobike我的贴纸功能

来源:互联网 发布:云米超能滤水壶 知乎 编辑:程序博客网 时间:2024/04/29 01:51

前言:

谈到摩拜,不得不提共享单车间的这场战争。当巨大的资本注入这个行业的时候,在短短的几个月就能发生翻天覆地的变化:无数的自行车行岌岌可危,骑行成为我们出行的一种新方式。我曾经认为的高损坏,高遗失等问题,在资本的推动下,甚至给了我一种这样的感觉:偷车的抱怨车太多,搞破坏的累到不行,资本的力量真是无穷尽!

正文:

言归正传,先上图回忆下,摩拜我的贴纸功能到底是什么样的


屏幕快照 2017-07-01 下午6.10.40.png

若要完成带有重力感应的小球,其实主要在两个点:

1.赋予小球重力属性及碰撞属性《UIDynamic》
2.手机移动时,重力方向动态改变 《CoreMotion》

此时,我们的目标就很明确了。

1.赋予小球重力属性及碰撞属性《UIDynamic》

1、UIDynamic隶属于UIKit框架,可以模拟现实世界动力驱动的动画,比如重力、碰撞、悬挂等。
2、任何遵守UIDynamicItem协议的对象可以进行物理仿真。UIView默认已经遵守了UIDynamicItem协议,因此任何UI控件都能做物理仿真;UICollectionViewLayoutAttributes类默认也遵守UIDynamicItem协议。

使用步骤

1、创建物理仿真器 UIDynamicAnimator

//bgView为仿真的有效范围_animator = [[UIDynamicAnimator alloc] initWithReferenceView:bgView];

2、添加物理仿真行为,UIDynamic提供了以下几种物理仿真行为:

UIGravityBehavior:重力行为
UICollisionBehavior:碰撞行为
UISnapBehavior:捕捉行为
UIPushBehavior:推动行为
UIAttachmentBehavior:附着行为
UIDynamicItemBehavior:动力元素行为

//添加重力仿真_gravityBeahvior = [[UIGravityBehavior alloc] init];

3、开始仿真

//添加仿真行为,开始仿真[_animator addBehavior:_gravityBeahvior];

完成重力感应和碰撞效果的小球,只需遵循以上三个步骤,具体细节可以直接看Demo。

细节

按照上面三个步骤,实际我们已经能够初尝这个动画效果了。但是,里面也有很多细节需要注意。
1、关于小球初始位置的处理。摩拜我的贴纸中,每次进入都是默认从顶部开始坠落。所以我为每个小球初始化了一个随机的x值,y=0。但是当小球个数过多时,可能会出现小球出现到仿真范围之外(摩拜中同样有此问题)。所以我将小球的初始x,y全部随机。

GBBall *ball = [[GBBall alloc] initWithFrame:CGRectMake([[self class] randValueBetween:0 and: (referenceViewSize.width - GBBALLWIDTH)], [[self class] randValueBetween:0 and: (referenceViewSize.height - GBBALLWIDTH)], GBBALLWIDTH, GBBALLWIDTH)];

2、在自定义的小球GBBall想碰撞时,有时候相邻之间的无法紧贴,原来此时小球仍以方形进行物理碰撞。iOS9在UIDynamicItem新增了collisionBoundsType(只读),所以需要改写GBBall中此属性

- (UIDynamicItemCollisionBoundsType)collisionBoundsType {    return UIDynamicItemCollisionBoundsTypeEllipse;}

2.手机移动时,重力方向动态改变 《CoreMotion》

CoreMotion是一个专门处理运动的框架,其中包含了两个部分加速度计和陀螺仪。通过此模块我们可以监听到手机的倾斜,更改重力仿真UIGravityBehavior的重力加速度方向。

[_motionManager startDeviceMotionUpdatesToQueue:queue withHandler:^(CMDeviceMotion * _Nullable motion, NSError * _Nullable error) {            if (!error) {                dispatch_async(dispatch_get_main_queue(), ^{                    _gravityBeahvior.gravityDirection = CGVectorMake(motion.gravity.x, -motion.gravity.y);                });            }        }];

我觉得看完这篇文章,对于摩拜我的贴纸中这个好玩的动画的实现,已经非常简单清晰。UIDynamicCoreMotion里面中,我没有做过细的描述,有兴趣的可以自己研究文档。
附上Demo:https://github.com/xxg90s/XXGravityBall