UIKit Dynamics框架

来源:互联网 发布:软件推广招聘 编辑:程序博客网 时间:2024/05/21 06:20


UIKit Dynamic框架介绍
            UIKit  Dynamic  框架最初是iOS 7版本的 IDevices 中引入的, 简单来说,UIKit Dynamic  通过在UIVIew 中整合现实 的一些行为,提供一中易于实现的方法来提升用户体验。用简单的术语来解释UIKit Dynamics ,其实它就是UIKit的基础物理引擎,不过他并不像传统的物理引擎一样是专门为游戏开发而设计的。当程序创建一个新的UIDynamucAnimator  并将其添加到UIView 中时,动态行为就会被激活,每个动画元素都可以对其属性和行为进行自定义,比如重力,碰撞检测,密度,摩擦,以及额外的一些属性
一共有6个附加类可以支持UIDynamicAnimator 元素自定义设置,分别是UIAttachmentBehavior,UICollisionBehavior,UIDynamicItemBehavior UIGravityBehavior,UIPushBehavior和UISnapBehavior。每个元素都允许制定自定义属性并且在相应的视图中以真实的行为和动画反映出来。
   
UIKIt Dynamic各种效果的实现:

  1.重力效果
       实现代码
      
  
UIDynamicAnimator* animator= [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; UIGravityBehavior* gravityBeahvior = [[UIGravityBehavior alloc] initWithItems:@[frogImageView]]; [gravityBeahvior setGravityDirection:CGVectorMake(0.0f, 0.1f)]; //property changed after printing of the book  [animator addBehavior:gravityBeahvior];
    注意:动态元素必须作为引用视图的自视图,如果动态元素不是子视图,动画对象就不会移动。
    力度1.0大致等于9.80655m/s^2 即地球的重力加速度 默认的方向是向下的,如果yComponent的值为负值 ,重力方向向上,同样的重力也可以指向X轴。这里设置的是方向向下的十分之一的重力加速度。

2.碰撞效果
  CollisionModel:
      UICollisionBehaviorModeItems 是元素相互碰撞
      UICollisionBehaviorModeBoundaries 元素不会碰撞,但回合边界发生碰撞
      UICollisionBehaviorModeEverything  元素会发生碰撞,边界也会发生碰撞

    要想程序和边界发生互动关系,需要先对边界进行定义。最简单的定义方法局势通过UICollisionBehavior 对象上设置一个称为translatesReferenceBoundsintoBoundary的布尔参数边界也可以遵循某种路径,使用addBoundaryWithidentifier:forPath:方法遵循NSBezierpath表示路径,或者使用addBoundaryWithIdentifier:fromPoint:toPoint:方法时期遵循基于两点表示的路径

 UICollisionBehavior 还提供了一个代理回调用于遵循UICollisionBehavior 协议

       collisionBehavior.collisionDelegate = self; 

UICollisionBehaviorDelegate 代理有4个回调方法,两个用于碰撞开始,两个用于碰撞结束,每个回调集都有一个方法用来定义边界是否出现碰撞,所有方法都提供了都导致回调方法触发的对象的引用。检测碰撞开始的方法还提供了以个CGPoint对象,用于记录发生的确切位置.


-(void)collisionBehavior:(UICollisionBehavior *)behavior beganContactForItem:(id<UIDynamicItem>)item withBoundaryIdentifier:(id<NSCopying>)identifier atPoint:(CGPoint)p{    if([item isEqual:frogImageView])        collisionOneLabel.text = @"Frog Collided";    if([item isEqual:dragonImageView])        collisionTwoLabel.text = @"Dragon Collided";}-(void)collisionBehavior:(UICollisionBehavior *)behavior endedContactForItem:(id<UIDynamicItem>)item withBoundaryIdentifier:(id<NSCopying>)identifier{    //collision has ended contact}

3.附着效果
 附着效果定义了两个对象间的动态连接,可实现两个移动对象间的绑定关系,默认情况下,UIAttachmentBehaviors都是固定在对象中心的附着点
可以通过程序自行设置为对象上的任何一点

 UIDynamicAnimator  *animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];    UICollisionBehavior* collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[dragonImageView, frogImageView]];        CGPoint frogCenter = CGPointMake(frogImageView.center.x, frogImageView.center.y);    self.attachmentBehavior = [[UIAttachmentBehavior alloc] initWithItem:dragonImageView attachedToAnchor:frogCenter];        [collisionBehavior setCollisionMode: UICollisionBehaviorModeBoundaries];    collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;        [animator addBehavior:collisionBehavior];    [animator addBehavior:self.attachmentBehavior];


为了改变两个对象间的附着距离,还可以对附着视图的长度属性进行更新。附着点自身不需要是对象的中心点,可以通过setAnchorPoint方法设置任意偏移量作为附着点。
4.弹跳效果
弹跳效果是附着效果的扩展,UIKit Dynamics 框架可以在UIAttachmentBehavior上设置一些额外的属性比如频率和阻尼
 UIAttachmentBehavior   设置的三个属性
      1.setFrequency 用于设置对象的振幅或者摆动大小
      2.setDamping 用于校平动画峰值
      3.setLength 该属性也是根据其初始位置进行调整的
   UIDynamicAnimator* animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];    UICollisionBehavior* collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[dragonImageView, frogImageView]];    UIGravityBehavior* gravityBeahvior = [[UIGravityBehavior alloc] initWithItems:@[dragonImageView]];    CGPoint frogCenter = CGPointMake(frogImageView.center.x, frogImageView.center.y);    self.attachmentBehavior = [[UIAttachmentBehavior alloc] initWithItem:dragonImageView attachedToAnchor:frogCenter];    [self.attachmentBehavior setFrequency:1.0f];    [self.attachmentBehavior setDamping:0.1f];    [self.attachmentBehavior setLength: 100.0f];        [collisionBehavior setCollisionMode: UICollisionBehaviorModeBoundaries];    collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;        [animator addBehavior:gravityBeahvior];    [animator addBehavior:collisionBehavior];    [animator addBehavior:self.attachmentBehavior];


5.瞬间移位
元素在视图中可以动态的瞬间位移到另一个点,每个UISnapBehavior 一次仅能关联一个单独的元素,并且在初始化的过程中元素的终点位置就已经被设置好,每个属性阻尼系数也可以被指定,泳衣影响动作的移动速度
 CGPoint point = [gesture locationInView:self.view]; UIDynamicAnimator*   animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];    UISnapBehavior* snapBehavior = [[UISnapBehavior alloc] initWithItem:frogImageView snapToPoint:point];    snapBehavior.damping = 0.75f;    [animator addBehavior:snapBehavior];

6.推力效果
UIKit Dynamics 还支持对力度的运用
 UIDynamicAnimator* animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];        UICollisionBehavior* collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[dragonImageView]];    collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;    [animator addBehavior:collisionBehavior];        UIPushBehavior *pushBehavior = [[UIPushBehavior alloc] initWithItems:@[dragonImageView] mode:UIPushBehaviorModeInstantaneous];    pushBehavior.angle = 0.0;    pushBehavior.magnitude = 0.0;        self.pushBehavior = pushBehavior;    [animator addBehavior:self.pushBehavior];


此时运行上面的代码视图将会始终固定在屏幕上,因为还没有对推力效果设置任何参数

 CGPoint point = [gesture locationInView:self.view];    CGPoint origin = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds));    CGFloat distance = sqrtf(powf(point.x-origin.x, 2.0)+powf(point.y-origin.y, 2.0));    CGFloat angle = atan2(point.y-origin.y,point.x-origin.x);    distance = MIN(distance, 100.0);        [self.pushBehavior setMagnitude:distance / 100.0];    [self.pushBehavior setAngle:angle];    [self.pushBehavior setActive:TRUE];

除了可以手动设置角度和加速度的值之外,还可以对指定目标点设置使用setTargetPoint:forItem:方法自动进行计算,有必要对视图中的一部分是施加力的效果,受理点并不一定是对象中心点,使用setXComponent:yComponent:方法可以指定一个CGpoint类型的点作为受力点有两种类型的力可以应用,--UIPushBehaviorModeContinuous 和UIPushBehaviorModeInstantaneous 持续的力会推动对象不断加速,瞬间的力会直接作用到对象上。


7.元素属性

动态元素有许多默认的预设属性,这些属性都可以自定义设置,用来表示对象针对物理引擎的不同响应。

 UIDynamicAnimator*   animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];        UIGravityBehavior* gravityBehavior = [[UIGravityBehavior alloc] initWithItems:@[dragonImageView, frogImageView]];        UICollisionBehavior* collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[dragonImageView, frogImageView]];    collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;    UIDynamicItemBehavior* propertiesBehavior = [[UIDynamicItemBehavior alloc] initWithItems:@[frogImageView]];    propertiesBehavior.elasticity = 1.0f;    propertiesBehavior.allowsRotation = NO;    propertiesBehavior.angularResistance = 0.0f;    propertiesBehavior.density = 3.0f;    propertiesBehavior.friction = 0.5f;    propertiesBehavior.resistance = 0.5f;        [animator addBehavior:propertiesBehavior];    [animator addBehavior:gravityBehavior];    [animator addBehavior:collisionBehavior];

                                       UIDynamicItem 属性及其描述


allowsRotation :一个布尔值,用于指定元素是否根据力度进行旋转,默认值是YES。

angularResistance:一个位于0.0到CGFLOAT_MAX范围内的CGFloat 值,用于指示带有角度的阻尼值,这个数值越大,旋转的减速就越快。

density: 用于表示密度,100X100对象的默认密度是1.0,100X200对象的默认密度是2.0,调整密度的大小会影响重力效果和碰撞效果的反映

elasticity:有效值介于0.0到1.0 用于指示当对象间发生碰撞时弹力大小,0.0表示不发生弹跳,1.0表示整个力度会应用到碰撞对象上

friction:当两个元素相互滑动时的线性阻力,0.0表示无摩擦力,1.0表示最大摩擦力,此外,亦可以使用大于1.0的只表示额外的阻力

resistance:开放空间中玉带的线性阻力,取值范围为0.0到CGFLOAT_MAX。0.0表示无阻力,1.0表示当没有力作用于元素时元素应该停止移动。




示例代码下载地址:https://github.com/dfsw/icf