[iOS]UIDynamicAnimator动画

创建动画

UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];

协议代理

@protocol UIDynamicAnimatorDelegate <NSObject>

@optional
- (void)dynamicAnimatorWillResume:(UIDynamicAnimator *)animator;
- (void)dynamicAnimatorDidPause:(UIDynamicAnimator *)animator;

@end

属性

// 行为执行时间
@property (nonatomic, readonly) NSTimeInterval elapsedTime;
// 判断是否正在执行
@property (nonatomic, readonly, getter = isRunning) BOOL running;

设置动画组件Item的动力属性

UIDynamicItemBehavior

UIDynamicItemBehavior *dynamic = [[UIDynamicItemBehavior alloc] init];
[animator addBehavior:dynamic];
[dynamic addItem:view];

// 相关属性
@property (readwrite, nonatomic) CGFloat elasticity; // Usually between 0 (inelastic) and 1 (collide elastically)
@property (readwrite, nonatomic) CGFloat friction; // 0 being no friction between objects slide along each other
@property (readwrite, nonatomic) CGFloat density; // 1 by default
@property (readwrite, nonatomic) CGFloat resistance; // 0: no velocity damping
@property (readwrite, nonatomic) CGFloat angularResistance; // 0: no angular velocity damping

为动画组件添加具体行为

吸引行为 UISnapBehavior

UISnapBehavior *snap = [[UISnapBehavior alloc]
                        initWithItem:view
                        snapToPoint:CGPointMake(200, 300)];
snap.damping = 0.9;//阻尼系数
[animator addBehavior:snap];

重力行为 UIGravityBehavior

UIGravityBehavior *gravity = [[UIGravityBehavior alloc] init];
// 重力矢量方向 默认为 (0,1)
gravity.gravityDirection = CGVectorMake(0, 1);
// 重力大小
gravity.magnitude = 5;
[animator addBehavior:gravity];
[gravity addItem:view];

碰撞行为 UICollisionBehavior

UICollisionBehavior *collision = [[UICollisionBehavior alloc] init];
// 边界刚体碰撞
collision.translatesReferenceBoundsIntoBoundary = YES;
[animator addBehavior:collision];
[collision addItem:view];

作用力行为 UIPushBehavior

UIPushBehavior *push = [[UIPushBehavior alloc] initWithItems:@[view]
                                                        mode:UIPushBehaviorModeInstantaneous];
//    UIPushBehaviorModeContinuous 持续作用力
//    UIPushBehaviorModeInstantaneous 瞬间作用力
push.active = YES;
push.pushDirection = CGVectorMake(1, 0);
[animator addBehavior:push];

效果演示

UIDynamicItemBehavior+UIGravityBehavior+UICollisionBehavior

- (void)viewDidLoad
{
  [super viewDidLoad];
  // Do any additional setup after loading the view, typically from a nib.
  
  animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
  
  dynamic = [[UIDynamicItemBehavior alloc]init];
  dynamic.elasticity = 0.7;// 弹力系数
  [animator addBehavior:dynamic];
  
  gravity = [[UIGravityBehavior alloc]init];
  gravity.gravityDirection = CGVectorMake(0, 1);// 重力矢量方向
  [animator addBehavior:gravity];
  
  collision = [[UICollisionBehavior alloc]init];
  collision.translatesReferenceBoundsIntoBoundary = YES;// 边界刚体碰撞
  [animator addBehavior:collision];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
  CGFloat width = self.view.frame.size.width;
  
  int x = arc4random()%(int)width;
  int z = arc4random()%20;
  
  UIView *view = [[UIView alloc]initWithFrame:CGRectMake(x, 10, 20+z, 20+z)];
  view.backgroundColor = [UIColor greenColor];
  view.layer.borderColor = [UIColor blueColor].CGColor;
  view.layer.borderWidth = 1.0;
  view.layer.masksToBounds = YES;
  [self.view addSubview:view];
  
  
  [dynamic addItem:view];
  [gravity addItem:view];
  [collision addItem:view];
}

UIPushBehavior+UIGravityBehavior

- (void)viewDidLoad
{
  [super viewDidLoad];
  // Do any additional setup after loading the view, typically from a nib.
  
  animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
  
  UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)];
  [self.view addGestureRecognizer:tap];
  
  gravity = [[UIGravityBehavior alloc] init];
  gravity.gravityDirection = CGVectorMake(0, 1);
  gravity.magnitude = 10.0;
  [animator addBehavior:gravity];
}

- (void)tap:(UITapGestureRecognizer *)tap
{
  CGPoint point = [tap locationInView:self.view];
  
  for (CGFloat i = 0 ; i < M_PI*2; i = i + 0.2)
  {
    UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 10, 10)];
    view.center = point;
    view.backgroundColor = [UIColor blueColor];
    view.layer.cornerRadius = 5;
    view.layer.masksToBounds = YES;
    [self.view addSubview:view];
    
    UIPushBehavior *push = [[UIPushBehavior alloc] initWithItems:@[view]
                                                            mode:UIPushBehaviorModeInstantaneous];
    push.active = YES;
    push.angle = i;
    push.magnitude = 0.05;
    [animator addBehavior:push];
    
    [gravity addItem:view];
  }
}

 

UIDynamicItemBehavior+UICollisionBehavior+UISnapBehavior

- (void)viewDidLoad
{
  [super viewDidLoad];
  // Do any additional setup after loading the view, typically from a nib.
  
  animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
  
  dynamic = [[UIDynamicItemBehavior alloc]init];
  dynamic.elasticity = 0.7;// 弹力系数
  [animator addBehavior:dynamic];
  
  collision = [[UICollisionBehavior alloc]init];
  collision.translatesReferenceBoundsIntoBoundary = YES;// 边界刚体碰撞
  [animator addBehavior:collision];
  
  CGFloat width = self.view.frame.size.width;
  CGFloat height = self.view.frame.size.height;
  
  red = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
  red.center = CGPointMake(width/2, height/2+100);
  red.backgroundColor = [UIColor redColor];
  red.layer.cornerRadius = 15.0;
  red.layer.masksToBounds = YES;
  [self.view addSubview:red];
  
  [collision addItem:red];
  
  UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)];
  [self.view addGestureRecognizer:tap];
}

- (void)tap:(UITapGestureRecognizer *)tap
{
  CGPoint point = [tap locationInView:self.view];
  
  UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
  view.center = point;
  view.backgroundColor = [UIColor blueColor];
  view.layer.cornerRadius = 10.0;
  view.layer.masksToBounds = YES;
  [self.view addSubview:view];
  
  [collision addItem:view];
  
  UISnapBehavior *snap = [[UISnapBehavior alloc]
                          initWithItem:view
                          snapToPoint:red.center];
  snap.damping = 0.1;
  [animator addBehavior:snap];
  
  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    [animator removeBehavior:snap];
  });
}

原文地址:https://www.cnblogs.com/EverNight/p/7029052.html