1、CoreAnimation的结构如下
2、CoreAnimation类介绍
(1)CAAnimation ---> CoreAnimation的基础类
两个代理方法,监听动画的开始和结束
- (void)animationDidStart:(CAAnimation *)anim;
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
(2)CABasicAnimation ---> 基本动画
@property(nullable, strong) id fromValue;
@property(nullable, strong) id toValue;
@property(nullable, strong) id byValue;
①实现大小、角度、位置的变化通过transform来实现:
CATransform3D transform = CATransform3D + (Make)+ Translate、Scale、Rotation
animation.toValue = [NSValue valueWithCATransform3D:transform];
//旋转
- (void)rotation
{
//实现180度的无限旋转
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform"];
anim.duration = 1;
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
anim.byValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI_2, 0, 0, 1)];
anim.removedOnCompletion = NO;
anim.fillMode = kCAFillModeForwards;
[self.myView.layer addAnimation:anim forKey:nil];
}
//位置
- (void)positon
{
//实现位置的移动
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform"];
CATransform3D form = CATransform3DMakeTranslation(350, 350, 0);
anim.toValue = [NSValue valueWithCATransform3D:form];
anim.duration = 1;
anim.removedOnCompletion = NO;
anim.fillMode = kCAFillModeForwards;
[self.myView.layer addAnimation:anim forKey:nil];
}
//大小
- (void)scale
{
//实现大小的变化
CABasicAnimation *anim = [CABasicAnimation animation];
anim.keyPath = @"transform";
CATransform3D form = CATransform3DMakeScale(1.2, 1.2, 1);
anim.toValue = [NSValue valueWithCATransform3D:form];
anim.duration = 0.5;
anim.repeatCount = MAXFLOAT;
anim.autoreverses = YES;
[self.myView.layer addAnimation:anim forKey:nil];
}
②实现大小、位置的变化通过bounds、position来实现:
//大小
- (void)scale
{
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"bounds"];
anim.duration = 2;
anim.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 30, 30)];
[_myView.layer addAnimation:anim forKey:nil];
}
//位置
- (void)positon
{
CABasicAnimation *anim = [CABasicAnimation animation];
anim.keyPath = @"position";
anim.toValue = [NSValue valueWithCGPoint:CGPointMake(250, 500)];
// 取消反弹
anim.removedOnCompletion = NO;
anim.fillMode = kCAFillModeForwards;
[_myView.layer addAnimation:anim forKey:nil];
}
(3)CAKeyframeAnimation --->关键帧动画
@property(nullable, copy) NSArray *values;
@property(nullable, copy) NSArray<NSNumber *> *keyTimes;
@property(nullable) CGPathRef path;
//位置1
- (void)position1
{
//多步动画
CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
animation.keyPath = @"position.x";
animation.values = @[ @0, @10, @-10, @10, @0 ];
//设置每一帧执行的时间长短 这个的取值为0-1,代表占用时间的比例
animation.keyTimes = @[ @0, @(1 / 6.0), @(3 / 6.0), @(5 / 6.0), @1 ];
animation.duration = 0.4;
//设置帧的中间值如何计算
animation.calculationMode = kCAAnimationPaced;
//这个属性确定动画执行的状态是否叠加在控件的原状态上
//默认设置为NO,如果我们执行两次位置移动的动画,会从同一位置执行两次
//如果设置为YES,则会在第一次执行的基础上执行第二次动画
animation.additive = YES;
//如果设置为YES,代表动画每次重复执行的效果会跟上一次相反
animation.autoreverses = YES;
[self.myView.layer addAnimation:animation forKey:@"position1"];
self.myView.layer.zPosition = 1;
}
//位置2
- (void)position2
{
//沿贝塞尔曲线的动画
// 这个方法将创建椭圆形路径
CGRect boundingRect = CGRectMake(0, 0, 300, 300);
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:boundingRect cornerRadius:150];
CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
animation.keyPath = @"position";
//设置一个路径
animation.path = path.CGPath;
animation.duration = 4;
animation.additive = YES;
animation.repeatCount = HUGE_VALF;
animation.calculationMode = kCAAnimationPaced;
animation.rotationMode = kCAAnimationRotateAuto;
[self.myView.layer addAnimation:animation forKey:nil];
}
(4)CASpringAnimation ---> 弹性动画
-(void)springAnimation{
CASpringAnimation *animation = [CASpringAnimation animationWithKeyPath:@"position"];
animation.toValue = [NSValue valueWithCGPoint:CGPointMake(175, 400)];
//质量,影响图层运动时的弹簧惯性,质量越大,弹簧拉伸和压缩的幅度越大
//如果把质量改成10,则动画变成 动画的速度变慢,并且波动幅度变大
animation.mass = 1;
//阻尼系数,阻止弹簧伸缩的系数,阻尼系数越大,停止越快
animation.damping = 30;
//初始速率 动画视图的初始速度大小
animation.initialVelocity = 10;
//刚度 刚度系数越大,形变产生的力就越大,运动越快
animation.stiffness = 10;
animation.duration = animation.settlingDuration;
animation.fillMode = kCAFillModeForwards;
animation.removedOnCompletion = NO;
[self.myView.layer addAnimation:animation forKey:@"springAnimation"];
}
(5)CATransition ---> 转场动画
@property(copy) NSString *type; 动画过渡类型 ----->
fade',
moveIn',push' and
reveal'. Defaults tofade'. @property(nullable, copy) NSString *subtype; 动画过渡方向 ----->
fromLeft',fromRight',
fromTop' and * `fromBottom'
- (void)transition
{
CATransition * ani = [CATransition animation];
ani.type = @"pageCurl";
ani.subtype = kCATransitionFromRight;
[self.myView.layer addAnimation:ani forKey:@""];
}
(5)CAAnimationGroup ---> 动画组
@property(nullable, copy) NSArray<CAAnimation *> *animations;
3、动画暂停和重启
//暂停
-(void)pauseAnimation
{
CFTimeInterval pausedTime = [self.myView.layer convertTime:CACurrentMediaTime() fromLayer:nil];
// 让CALayer的时间停止走动
self.myView.layer.speed = 0.0;
// 让CALayer的时间停留在pausedTime这个时刻
self.myView.layer.timeOffset = pausedTime;
}
//重启
-(void)resumeAnimation
{
CFTimeInterval pausedTime = self.myView.layer.timeOffset;
// 1. 让CALayer的时间继续行走
self.myView.layer.speed = 1.0;
// 2. 取消上次记录的停留时刻
self.myView.layer.timeOffset = 0.0;
// 3. 取消上次设置的时间
self.myView.layer.beginTime = 0.0;
// 4. 计算暂停的时间(这里也可以用CACurrentMediaTime()-pausedTime)
CFTimeInterval timeSincePause = [self.myView.layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
// 5. 设置相对于父坐标系的开始时间(往后退timeSincePause)
self.myView.layer.beginTime = timeSincePause;
}