前言:
UIKit Dynamics是iOS7.0新增的一组类和方法,可以赋予UIView逼真的行为和特征,从而改善用户体验。
要实现动态行为,需要先创建一个UIDynamicAnimator(力学动画生成器)的实例对象。对于每个力学动画生成器都可以使用各种属性和行为进行定制,如重力、碰撞检测、密度、摩擦力等。
有6个用于定制UIDynamicAnimator的类:UIAttachmentBehavior、UICollisionBehavior、UIDynamicItemBehavior、UIGravityBehavior、UIPushBehavior和UISnapBehavior。
1.重力
UIDynamicAnimator *animation = [[ UIDynamicAnimator alloc ]initWithReferenceView: self.view]; // 创建力学动画生成器
UIGravityBehavior * gravityBehavior = [[[UIGravityBehavior alloc] initWithItems:@[frogImageView]] autorelease];//创建重力行为对象,其中frogImageView是需要实现动画的视图,是self.view的子视图
[gravityBehavior setXComponent:0.0 yComponent:0.1];//设置方向和作用力(1.0为地球的重力加速度)
[animator addBehavior:gravityBehavior];//添加行为
注:动态物体必须是参考视图的子视图,否则力学动画生成器不会生成任何动态效果!
在UIKit Dynamics中,重力的方向可以不向下,如果将参数yComponent设置为负数,重力方向就会向上;同样可以改变xComponent。
2.碰撞
UICollisionBehavior是创建碰撞行为,和重力行为创建方式一样,使用受影响的视图进行初始化。除了受影响的视图外,还需要设置碰撞对象:UICollisionBehaviorModeItems导致物体相互碰撞;UICollisionBehaviorModeBoundaries导致物体不相互碰撞,只与边界发生碰撞;UICollisionBehaviorModeEverything导致物体既相互碰撞,又与边界碰撞。
要是物体与边界碰撞,必须要自定义边界。边界可以是NSBezierPath,也可以是两点之间,分别用addBoundaryWithIdentifier:forPath和addBoundaryWithIdentifier:fromPoint:toPoint进行设置;将UICollisionBehavior对象的translatesReferenceBoundsIntoBoundary设置为YES就是默认手机屏幕为边界。
UIDynamicAnimator *animation = [[ UIDynamicAnimator alloc ]initWithReferenceView: self.view]; // 创建力学动画生成器
UIGravityBehavior * gravityBehavior = [[[UIGravityBehavior alloc] initWithItems:@[frogImageView]] autorelease];//创建重力行为对象
[gravityBehavior setXComponent:0.0 yComponent:0.1];
UICollisionBehavior *collisionBehavior = [[[UICollisionBehavior alloc] initWithItems:@[frogImageView] ]autorelease];//创建碰撞行为对象
collisionBehavior.translateReferenceBoundsIntoBoundary = YES;//设置边界
[collisionBehavior setCollisionMode:UICollisionBehaviorModeBoundaries]; //设置碰撞对象
[animator addBehavior:gravityBehavior];//添加行为
[animator addBehavior:collisionBehavior];//添加行为
UICollisionBehavior对象还可以设置代理。有4个代理方法,其中两个是碰撞开始时调用,两个是碰撞结束时调用。所有方法都指向碰撞对象,碰撞开始的方法中还指出了接触点,一个CGPoint。
3.连接
UIAttachmentBehaviors可以指定两个物体之间动态连接,让一个物体的行为和移动受制于另一个。默认情况下,UIAttachmentBehaviors是将两个物体的中心点作为连接点,但是可以修改为任何一点。
UIDynamicAnimator *animation = [[ UIDynamicAnimator alloc ]initWithReferenceView: self.view]; // 创建力学动画生成器
UICollisionBehavior *collisionBehavior = [[[UICollisionBehavior alloc] initWithItems:@[frogImageView,secondImageView ] ]autorelease];//创建碰撞行为对象
collisionBehavior.translateReferenceBoundsIntoBoundary = YES;//设置边界
[collisionBehavior setCollisionMode:UICollisionBehaviorModeBoundaries]; //设置碰撞对象
CGPoint frogImageViewCenter = frogImageView.center;//获取中心点
self.attachmentBehavior = [[[UIAttachmentBehavior alloc] initWithItem:secondImageView attachedToAnchor:frogImageViewCenter] autorelease];
[animator addBehavior:collisionBehavior];
[animator addBehavior:self.attachmentBehavior];
这样两个视图就连接在了一起,连接物的长度是两个视图的初始距离。但此时frogImageView还不会移动,所以可以添加一个简单的手势。在frogImageView移动时更新中心点并且重新设置锚点:
- (viod)handleAttachmentGesture:(UIPanGestureRecognizer *)gesture {
CGPoint gesturePoint = [gesture locationInView:self.view];
frogImageView.center = gesturePoint;
[self.attachmentBehavior setAnchorPoint:gesture];
}
UIAttachmentBehavior还可以修改其他属性,如振动频率和阻尼。
[self.attachmentBehavior setFrequency:1.0];//设置振动频率
[self.attachmentBehavior setDamping:0.1f]; //设置震动峰值
[self.attachmentBehavior setLength:100.0f]; //设置运动后的距离
4.吸附
UISnapBehavior只能关联一个视图,初始化时必须指定运动的终点。这种行为是由请按手势触发的。
CGPoint point = [gesture locationInView:self.view];
UIDynamicAnimator *animation = [[ UIDynamicAnimator alloc ]initWithReferenceView: self.view]; // 创建力学动画生成器
UISnapBehavior *snapBehavior = [[[UISnapBehavior alloc] initWithItem:frogImageView snapToPoint:point] autorelease];
snapBehavior .damping = 0.75;//设置物体吸附时的弹跳力度
[animator addBehavior : snapBehavior];
5.推力
UIPushBehavior的使用比其他行为稍复杂。主要属性有力度(magnitude)和角度(angle)。
UIPushBehavior *pushBehavior = [[[UIPushBehavior alloc] initWithItems:@[frogImageView] mode: UIPushBehaviorModeInstantaneous] autorelease];//mode属性有两种,一种是瞬时里,一种是持续力
以屏幕中心为参考点,添加手势作为施加的力,里中心点越远,作用力越大。
计算距离和角度,使用self.pushBehavior setMagnitude:和self.PushBehavior setAngle:设置。最后[self.pushBehavior setActive:TRUE];
6.物体属性
UIDynamicItemBehavior可以用来修改物体的属性。初始化方法和其他行为大同小异,主要是设置UIDynamicItemBehavior对象的属性。
allowsRotation:一个Boolean值,指定物体在受力时是否会旋转,默认为YES。
angularResistance:一个CGFloat值,取值范围为0.0~CGFLOAT_MAX;指定旋转阻力,其值越大,旋转速度下降越快。
density:物体密度。默认情况下100X100点的物体质量为1.0,100X200的物体质量为2.0。调整密度会影响重力和碰撞效果。
elasticity:取值范围为0.0~1.0,表示与其他物体碰撞时的弹性。0.0表示没有弹性,1.0表示反弹作用力和碰撞作用力相等。
friction:物体之间的滑动阻力。0.0表示没有阻力,1.0表示阻力很大,但可将该值设置大于1的某个值继续增加阻力。
resistance:空气阻力,取值范围为0.0~CGFLOAT_MAX。0.0表示没有空气阻力,1.0表示一旦其他力消失物体就会停下来。
7.其他属性和代理方法
UIDynamicAnimator都是使用addBehavior:添加行为,也可以使用removeBehavior:和removeAllBehavior删除行为,还可以通过behavior属性查看关联的行为,将会返回一个数组。还可以查询动画生成器是否在运行(running属性),更可以使用elapsedTime属性查询运行时长。UIDynamicAnimator还有一个代理(UIDynamicAnimatorDelegate),他包含两个代理方法,分别是处理暂停和继续的方法。开发人员不能主动暂停UIDynamicAnimator。
-(viod)dynamicAnimatorDidPause:(UIDynamicAnimator *)animator {
NSLog(@"Animator did pause");
}
-(viod)dynamicAnimatorWillResume:(UIDynamicAnimator *)animator {
NSLog(@"Animator will resume");
}
总结:以上是UIKit Dynamics的基本知识和组成部分,主要还是依赖于开发人员的创意。