前言:
谈到摩拜,不得不提共享单车间的这场战争。当巨大的资本注入这个行业的时候,在短短的几个月就能发生翻天覆地的变化:无数的自行车行岌岌可危,骑行成为我们出行的一种新方式。我曾经认为的高损坏,高遗失等问题,在资本的推动下,甚至给了我一种这样的感觉:偷车的抱怨车太多,搞破坏的累到不行,资本的力量真是无穷尽!
正文:
言归正传,先上图回忆下,摩拜我的贴纸功能到底是什么样的
若要完成带有重力感应的小球,其实主要在两个点:
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);
});
}
}];
我觉得看完这篇文章,对于摩拜我的贴纸中这个好玩的动画的实现,已经非常简单清晰。UIDynamic
与CoreMotion
里面中,我没有做过细的描述,有兴趣的可以自己研究文档。
附上Demo:https://github.com/xxg90s/XXGravityBall