[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]; }); }