UIKit Dynamics 用来模拟物理动作,有重力、碰撞、弹跳、附着、瞬间位移、推力、元素行为。下面分别是各个行为的效果图。
所有动画行为都要添加到一个UIDynamicAnimator中,需要绑定一个引用视图,动态行为的视图必须是引用视图的子视图。
分别来讲解
- 重力行为
- (void)startAnimation {
//animator必须是全局的,要不然没有动画效果
// UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
UIGravityBehavior *gravityBehavior = [[UIGravityBehavior alloc] initWithItems:@[self.ballView]];
[gravityBehavior setGravityDirection:CGVectorMake(0.0f, 0.1f)];//重力方向向下,0.1表示以地球重力十分之一的力下落。
[animator addBehavior:gravityBehavior];
}
这里只设置了重力行为,没有设置碰撞行为,所以小球会一直下落至不见。
- 碰撞行为
- (void)startCollidesion {
self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
//重力行为
UIGravityBehavior *gravityBehavior = [[UIGravityBehavior alloc] initWithItems:@[self.frogIV, self.dragonIV]];
gravityBehavior.gravityDirection = CGVectorMake(0.0, 0.1);
//碰撞行为
UICollisionBehavior *collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[self.frogIV, self.dragonIV]];
collisionBehavior.collisionMode = UICollisionBehaviorModeEverything;
collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
collisionBehavior.collisionDelegate = self;
[self.animator addBehavior:gravityBehavior];
[self.animator addBehavior:collisionBehavior];
}
#pragma mark - UICollisionBehaviorDelegate
- (void)collisionBehavior:(UICollisionBehavior *)behavior beganContactForItem:(nonnull id<UIDynamicItem>)item withBoundaryIdentifier:(nullable id<NSCopying>)identifier atPoint:(CGPoint)p {
if ([item isEqual:self.dragonIV]) {
self.dragonL.text = @"龙撞击到了地面";
}
if ([item isEqual:self.frogIV]) {
self.frogL.text = @"青蛙撞击到了地面";
}
}
- (void)collisionBehavior:(UICollisionBehavior *)behavior endedContactForItem:(id<UIDynamicItem>)item withBoundaryIdentifier:(id<NSCopying>)identifier {
NSLog(@"撞击结束");
}
碰撞行为可以设置代理,可以在碰撞开始和结束时做想要的操作。
- 附着行为
- (void)startAnimator {
//添加碰撞行为
self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
UICollisionBehavior *collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[self.frogIV, self.dragonIV]];
collisionBehavior.collisionMode = UICollisionBehaviorModeBoundaries;
collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
[self.animator addBehavior:collisionBehavior];
//添加附着行为
CGPoint frogCenter = CGPointMake(self.frogIV.center.x, self.frogIV.center.y);
//让龙的图片随着青蛙的中心点运动
UIAttachmentBehavior *attachmentBehavior = [[UIAttachmentBehavior alloc] initWithItem:self.dragonIV attachedToAnchor:frogCenter];
self.attachmentBehavior = attachmentBehavior;
[self.animator addBehavior:attachmentBehavior];
}
//让青蛙图片可以移动
- (IBAction)handleAttachmentGesture:(UIPanGestureRecognizer *)sender {
//将拖动的点设置为青蛙图片的中心点
CGPoint panPoint = [sender locationInView:self.view];
self.frogIV.center = panPoint;
self.attachmentBehavior.anchorPoint = panPoint;
}
让某个元素根据另一个元素的变化而变化。
- 弹跳行为
- (void)startAnimator {
UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
self.animator = animator;
UICollisionBehavior *collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[self.frogIV, self.dragonIV]];
collisionBehavior.collisionMode = UICollisionBehaviorModeBoundaries;
collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
UIGravityBehavior *gravityBehavior = [[UIGravityBehavior alloc] initWithItems:@[self.dragonIV]];
CGPoint frogCenter = CGPointMake(self.frogIV.center.x, self.frogIV.center.y);
UIAttachmentBehavior *attachmentBehavior = [[UIAttachmentBehavior alloc] initWithItem:self.dragonIV attachedToAnchor:frogCenter];
attachmentBehavior.frequency = 1.0f; //越大晃动越快
attachmentBehavior.damping = 0.1f; //越小晃动幅度越大
attachmentBehavior.length = 100.0f; //越大距离附着的点越远
[animator addBehavior:collisionBehavior];
[animator addBehavior:gravityBehavior];
[animator addBehavior:attachmentBehavior];
}
其实就是附着行为的几个属性设置,frequency、damping、length。
- 瞬间位移
- (IBAction)handleTapGesture:(UITapGestureRecognizer *)sender {
// 手指点到哪儿,就让图片瞬间移动哪儿
CGPoint panPoint = [sender locationInView:self.view];
UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
self.animator = animator;
UISnapBehavior *snapBehavior = [[UISnapBehavior alloc] initWithItem:self.frogIV snapToPoint:panPoint];
snapBehavior.damping = 0.5;
[self.animator addBehavior:snapBehavior];
}
让某个元素瞬间移动到某个点
- 推力行为
- (void)startAnimator {
UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
self.animator = animator;
UICollisionBehavior *collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[self.dragonIV]];
collisionBehavior.collisionMode = UICollisionBehaviorModeBoundaries;
collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
UIPushBehavior *pushBehavior = [[UIPushBehavior alloc] initWithItems:@[self.dragonIV] mode:UIPushBehaviorModeContinuous];
self.pushBehavior = pushBehavior;
pushBehavior.magnitude = 0.0;
pushBehavior.angle = 0.0;
[self.animator addBehavior:collisionBehavior];
[self.animator addBehavior:pushBehavior];
}
- (IBAction)handlePanGesture:(UIPanGestureRecognizer *)sender {
//根据移动的点计算推力的角度和距离、
if (sender.state == UIGestureRecognizerStateEnded) {
CGPoint panPoint = [sender locationInView:self.view];
CGPoint originPoint = CGPointMake(CGRectGetMidX(self.dragonIV.bounds), CGRectGetMidY(self.dragonIV.bounds));
CGFloat angle = atan2(panPoint.y - originPoint.y, panPoint.x - originPoint.x);
CGFloat distance = sqrtf(powf(panPoint.x - originPoint.x, 2) + powf(panPoint.y - originPoint.y, 2));
distance = MIN(distance, 100);
self.pushBehavior.magnitude = distance/100;
self.pushBehavior.angle = angle;
self.pushBehavior.active = YES;
}
}
- 元素行为
- (void)startAnimator {
UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
self.animator = animator;
UIGravityBehavior *gravityBehavior = [[UIGravityBehavior alloc] initWithItems:@[self.dragonIV, self.frogIV]];
UICollisionBehavior *collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[self.dragonIV, self.frogIV]];
collisionBehavior.collisionMode = UICollisionBehaviorModeBoundaries;
collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
//只对青蛙图片设置元素属性,用龙图片进行对比
UIDynamicItemBehavior *propertiesBehavior = [[UIDynamicItemBehavior alloc] initWithItems:@[self.frogIV]];
propertiesBehavior.elasticity = 1.0f;
propertiesBehavior.allowsRotation = NO;
propertiesBehavior.angularResistance = 0.0f;
propertiesBehavior.density = 3.0f;
propertiesBehavior.friction = 0.5f;
propertiesBehavior.resistance = 1.0f;
[self.animator addBehavior:gravityBehavior];
[self.animator addBehavior:collisionBehavior];
[self.animator addBehavior:propertiesBehavior];
}