UIDynamic

2018-02-09  本文已影响15人  Carson_Zhu

简介

UIDynamiciOS 7之后新添加的一些物理仿真动画库,包含在UIKit框架中。

UIDynamic中的三个重要概念:

UIDynamicAnimator

UIDynamicItem

UIDynamicBehavior

在通常情况下我们不会直接使用UIDynamicBehavior类,而是使用它的子类们。在开始介绍它的子类前,先来看看UIDynamicBehavior作为父类的一些属性和方法:

1. UIGravityBehavior(重力行为)

实例

UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.redView]];
gravity.gravityDirection = CGVectorMake(0, 1);
//gravity.angle = M_PI*0.01;    
[self.animator addBehavior:gravity];
效果:
2. UICollisionBehavior (碰撞行为)

实例一: 元素之间的碰撞

UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.redView]];
gravity.gravityDirection = CGVectorMake(1, 1);
[self.animator addBehavior:gravity];
    
UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[self.redView, self.blueView]];
collision.collisionMode = UICollisionBehaviorModeItems;
collision.translatesReferenceBoundsIntoBoundary = YES;
[self.animator addBehavior:collision];
效果:

实例二: 边界碰撞

UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.redView]];
gravity.gravityDirection = CGVectorMake(1, 1);
[self.animator addBehavior:gravity];
    
UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[self.redView, self.blueView]];
collision.collisionMode = UICollisionBehaviorModeBoundaries;
collision.translatesReferenceBoundsIntoBoundary = YES;
[self.animator addBehavior:collision];
效果:

实例三: 碰撞所有

UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.redView]];
gravity.gravityDirection = CGVectorMake(1, 1);
[self.animator addBehavior:gravity];
    
UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[self.redView, self.blueView]];
collision.collisionMode = UICollisionBehaviorModeEverything;
collision.translatesReferenceBoundsIntoBoundary = YES;
[self.animator addBehavior:collision];
效果:

实例四: 碰撞边界内边距

UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.redView]];
gravity.gravityDirection = CGVectorMake(1, 1);
[self.animator addBehavior:gravity];
    
UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[self.redView, self.blueView]];
collision.collisionMode = UICollisionBehaviorModeEverything;
[collision setTranslatesReferenceBoundsIntoBoundaryWithInsets:UIEdgeInsetsMake(50, 50, 50, 50)];
// 检测边距和内边距互相冲突,以最后设置为准
// collision.translatesReferenceBoundsIntoBoundary = NO;
[self.animator addBehavior:collision];
效果:

实例五: 贝塞尔曲线边界

UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.redView]];
gravity.gravityDirection = CGVectorMake(1, 1);
[self.animator addBehavior:gravity];
    
UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[self.redView]];
collision.collisionMode = UICollisionBehaviorModeEverything;
    
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(50, 70, 200, 400)];
[collision addBoundaryWithIdentifier:@"path" forPath:path];
[self.animator addBehavior:collision];
效果:

实例六: 两点组成的线段边界

UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.redView]];
gravity.gravityDirection = CGVectorMake(1, 1);
[self.animator addBehavior:gravity];
    
UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[self.redView]];
collision.collisionMode = UICollisionBehaviorModeEverything;
    
[collision addBoundaryWithIdentifier:@"line" fromPoint:CGPointMake(200, 100) toPoint:CGPointMake(50, 400)];
[self.animator addBehavior:collision];
效果:
3. UIAttachmentBehavior (附着行为)

附着行为一般都是添加手势,让视图跟着手势移动,因为一般都是与手势搭配使用。

实例一: 元素和锚点

UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.redView]];
gravity.gravityDirection = CGVectorMake(1.0f, 1.0f);
[self.animator addBehavior:gravity];
    
UIAttachmentBehavior *attachment = [[UIAttachmentBehavior alloc] initWithItem:self.redView attachedToAnchor:CGPointMake(200, 300)];
attachment.length = 50;
[self.animator addBehavior:attachment];
效果:

实例二: 元素和锚点加偏移

UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.redView]];
gravity.gravityDirection = CGVectorMake(1.0f, 1.0f);
[self.animator addBehavior:gravity];
    
UIAttachmentBehavior *attachment = [[UIAttachmentBehavior alloc] initWithItem:self.redView offsetFromCenter:UIOffsetMake(25, 0) attachedToAnchor:CGPointMake(200, 300)];
attachment.length = 50;
[self.animator addBehavior:attachment];
效果:

实例三: 元素与元素

UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.redView]];
gravity.gravityDirection = CGVectorMake(0, 1.0f);
[self.animator addBehavior:gravity];
    
UIAttachmentBehavior *attachment = [[UIAttachmentBehavior alloc] initWithItem:self.redView attachedToItem:self.blueView];
attachment.length = 100;
[self.animator addBehavior:attachment];
效果:

实例四: 手势依附

// 添加手势
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] init];
[pan addTarget:self action:@selector(panDidHandler:)];
[self.view addGestureRecognizer:pan];

// 手势响应
- (void)panDidHandler:(UIPanGestureRecognizer *)pan {
    CGPoint location = [pan locationInView:self.view];
    if (pan.state == UIGestureRecognizerStateBegan) {
        self.attachmentBehavior = [[UIAttachmentBehavior alloc] initWithItem:self.redView attachedToAnchor:location];
        [self.animator addBehavior:self.attachmentBehavior];
    } else if (pan.state == UIGestureRecognizerStateChanged) {
        self.attachmentBehavior.anchorPoint = location;
    } else if (pan.state == UIGestureRecognizerStateEnded) {
        [self.animator removeBehavior:self.attachmentBehavior];
    }
}
效果:
4. UIPushBehavior(推动行为)

实例一: 瞬间推动UIPushBehaviorModeInstantaneous

UIPushBehavior *pushBehavior = [[UIPushBehavior alloc] initWithItems:@[self.redView] mode:UIPushBehaviorModeInstantaneous];
pushBehavior.pushDirection = CGVectorMake(0.5, 0.5);
[self.animator addBehavior:pushBehavior];
    
UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[self.redView]];
collision.collisionMode = UICollisionBehaviorModeEverything;
collision.translatesReferenceBoundsIntoBoundary = YES;
[self.animator addBehavior:collision];

效果:


实例二: 连续推动UIPushBehaviorModeContinuous
UIPushBehavior *pushBehavior = [[UIPushBehavior alloc] initWithItems:@[self.redView] mode:UIPushBehaviorModeContinuous];
pushBehavior.pushDirection = CGVectorMake(0.5, 0.5);
[self.animator addBehavior:pushBehavior];
    
UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[self.redView]];
collision.collisionMode = UICollisionBehaviorModeEverything;
collision.translatesReferenceBoundsIntoBoundary = YES;
[self.animator addBehavior:collision];
效果:

实例三: 作用力中心偏移

UIPushBehavior *pushBehavior = [[UIPushBehavior alloc] initWithItems:@[self.redView] mode:UIPushBehaviorModeInstantaneous];
pushBehavior.pushDirection = CGVectorMake(0.5, 0.5);
[pushBehavior setTargetOffsetFromCenter:UIOffsetMake(-25, 0) forItem:self.redView];
[self.animator addBehavior:pushBehavior];
    
UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[self.redView]];
collision.collisionMode = UICollisionBehaviorModeEverything;
collision.translatesReferenceBoundsIntoBoundary = YES;
[self.animator addBehavior:collision];
效果:
5. UIDynamicItemBehavior (动力行为)

因为可以设置摩擦力、弹力、密度、阻力等参数,在模拟视图运动的能量损失。

实例:

- (void)addDynamicItem {
    UIDynamicItemBehavior *dynamicItem = [[UIDynamicItemBehavior alloc] initWithItems:@[self.redView]];
    dynamicItem.elasticity = 0.5f; // 弹性系数
    dynamicItem.friction = 1.0f; // 摩擦系数
    dynamicItem.density = 10.0f; // 相对质量密度
    dynamicItem.resistance = 10.0f; // 线性阻尼
    dynamicItem.angularResistance = 10.0f; // 角度阻尼
    [self.animator addBehavior:dynamicItem];
    
    // 推动行为
    UIPushBehavior *pushBehavior = [[UIPushBehavior alloc] initWithItems:@[self.redView] mode:UIPushBehaviorModeInstantaneous];
    pushBehavior.pushDirection = CGVectorMake(0.5, 0);
    pushBehavior.magnitude = 20;
    [pushBehavior setTargetOffsetFromCenter:UIOffsetMake(0, -25) forItem:self.redView];
    [self.animator addBehavior:pushBehavior];
    
    // 碰撞行为
    UICollisionBehavior *collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[self.redView]];
    collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
    [self.animator addBehavior:collisionBehavior];
}
效果:
6. UISnapBehavior (捕获行为)

捕获行为是定义一个动态元素运动到指定点,运动过程伴随弹簧效果。

实例:

UISnapBehavior *snapBehavior = [[UISnapBehavior alloc] initWithItem:self.redView snapToPoint:CGPointMake(200, 300)];
snapBehavior.damping = 0.2f;
[self.animator addBehavior:snapBehavior];
效果:
上一篇 下一篇

猜你喜欢

热点阅读