CAAnimation是QuartzCore框架里面定义的
CAAnimation主要是遵循了 CAMediaTiming 协议,拥有了一些动画的属性
属性 | 参数类型 | 备注 |
---|---|---|
beginTime | CFTimeInterval | 指定动画开始的时间。(设置动画beginTime为1,动画将延时1秒后开始执行) |
duration | CFTimeInterval | 动画时长;(默认值为0,但是实际动画默认持续时间为0.25秒) |
speed | float | 动画执行的速度;(默认值为0,减少它会减慢动画的时间,增加它会加快速度)(设置speed为2时,则动画实际执行时间是duration的一半) |
timeOffset | CFTimeInterval | 动画时间偏移量;(设置时长3秒动画的timeOffset为1时,动画会从1秒位置执到最后,再执行之前跳过的部分) |
repeatCount | float | 重复的次数。不停重复设置为 HUGE_VALF |
repeatDuration | CFTimeInterval | 设置动画的时间。在该时间内动画一直执行,不计次数。 |
autoreverses | BOOL | 动画结束时是否执行逆动画 ,动画从初始值执行到最终值,是否会反向回到初始值;(设置为YES,动画完成后将以动画的形式回到初始位置) |
fillMode | NSStrinng | 决定当前对象在非动画时间端段的动画属性值,如动画开始之前和动画结束之后 |
timingFunction | CAMediaTimingFunction | 设置动画的速度变化 |
fromValue | id | 所改变属性的起始值 |
toValue | id | 所改变属性的结束时的值 |
byValue | id | 所改变属性相同起始值的改变量 |
removedOnCompletion | BOOL | 动画完成之后是否还原,默认为yes。 |
一些常用的animationWithKeyPath值的总结
值 | 使用形式 | 备注 |
---|---|---|
transform.scale | @(0.8) | 比例转化,在所有方向上进行缩放 |
transform.scale.x | @(0.8) | 宽的比例 |
transform.scale.y | 高的比例 | @(0.8) |
transform.rotation.x | 围绕x轴旋转 | @(M_PI) |
transform.rotation.y | 围绕y轴旋转 | @(M_PI) |
transform.rotation.z | 围绕z轴旋转 | @(M_PI) |
cornerRadius | 圆角的设置 | @(50) |
backgroundColor | 背景颜色的变化 | (id)[UIColor grayColor].CGColor |
bounds | 中心不变,改变大小 | [NSValue valueWithCGRect:CGRectMake(0, 0, 50, 50)]; |
position | 中心改变) | [NSValue valueWithCGPoint:CGPointMake(300, 300)]; |
contents | 改变内容,比如UIImageView的图片 | imageAnima.toValue = (id)[UIImage imageNamed:@"name"].CGImage; |
opacity | 透明度 | @(0.6) |
contentsRect.size.width | 横向拉伸缩放 | @(0.3)最好是0~1之间的 |
contentsRect.size.height | 纵向拉伸缩放 | @(0.3)最好是0~1之间的 |
核心动画Core Animation常用类的继承关系
动画类 | 动画特性 |
---|---|
CAMediaTiming | 协议;定义了一段动画内用于控制时间的属性的集合 |
CAAnimation | 抽象类;作为所有动画类型父类,不可直接使用 |
CAPropertyAnimation | 抽象类;作为基础动画和帧动画的父类,不可直接使用 |
CABasicAnimation | 基础动画;用于实现单一属性变化的动画 |
CAKeyFrameAnimation | 关键帧动画;用于实现单一属性连续变化的动画 |
CAAnimaitionGroup | 组动画;用于实现多属性同时变化的动画 |
CATrasition | 转场过渡动画; |
CAMediaTiming只有这两个代理方法 顾名思义,一个开始一个结束,CAAnimation实现代理方法不同于其他,CAAnimation不用声明CAAnimationDelegate。直接重写方法即可
/* Delegate methods for CAAnimation. */
@protocol CAAnimationDelegate <NSObject>
@optional
/* Called when the animation begins its active duration. */
//动画的开始的回调
- (void)animationDidStart:(CAAnimation *)anim;
/* Called when the animation either completes its active duration or
* is removed from the object it is attached to (i.e. the layer). 'flag'
* is true if the animation reached the end of its active duration
* without being removed. */
//动画结束的回调 。flag参数表明了动画是自然结束还是被打断的
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
@end
1.CABasicAnimation
通过设定起始点,终点,时间,动画会沿着你这设定点进行移动。可以看做特殊的CAKeyFrameAnimation
2.CAKeyframeAnimation
Keyframe顾名思义就是关键点的frame,你可以通过设定CALayer的始点、中间关键点、终点的frame,时间,动画会沿你设定的轨迹进行移动
3.CAAnimationGroup
Group也就是组合的意思,就是把对这个Layer的所有动画都组合起来。PS:一个layer设定了很多动画,他们都会同时执行,
4.CATransition
这个就是苹果帮开发者封装好的一些动画,
KeyFrame的意思是关键帧,所谓“关键”就是改变物体运动趋势的帧,在该点处物体将发生运动状态,比如矩形的四个角,抛物线的顶点等。
values 指明整个动画过程中的关键帧点
path 与values属性一样,同样是用于指定整个动画所经过的路径的。需要注意的是,values与path是互斥的,当values与path同时指定时,path会覆盖values,即values属性将被忽略。
keyTimes 是一个数组,用以指定每个子路径(AB,BC,CD)的时间。如果你没有显式地对keyTimes进行设置,则系统会默认每条子路径的时间为:ti=duration/(5-1),即每条子路径的duration相等,都为duration的1\4。当然,我们也可以传个数组让物体快慢结合。例如,你可以传入{0.0, 0.1,0.6,0.7,1.0},其中首尾必须分别是0和1,因此tAB=0.1-0, tCB=0.6-0.1, tDC=0.7-0.6, tED=1-0.7.....
timeFunctions 这个属性用以指定时间函数,类似于运动的加速度,有以下几种类型。记住,这是一个数组,你有几个子路径就应该传入几个元素
/** Timing function names. **/
CA_EXTERN NSString * const kCAMediaTimingFunctionLinear
CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0);//默认,匀速执行动画
CA_EXTERN NSString * const kCAMediaTimingFunctionEaseIn
CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0);//浅入,先慢慢加速,后突然停止
CA_EXTERN NSString * const kCAMediaTimingFunctionEaseOut
CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0);//先全速开始,再慢慢减速停止
CA_EXTERN NSString * const kCAMediaTimingFunctionEaseInEaseOut
CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0);//浅入浅出,先慢慢加速,再慢慢减速
CA_EXTERN NSString * const kCAMediaTimingFunctionDefault
CA_AVAILABLE_STARTING (10.6, 3.0, 9.0, 2.0);//效果同KCAMediaTimingFuncationEaseInEaseOut
calculationMode 该属性决定了物体在每个子路径下是跳着走还是匀速走,跟timeFunctions属性有点类似
/* `calculationMode' strings. */
CA_EXTERN CAAnimationCalculationMode const kCAAnimationLinear
API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));//线性,默认
CA_EXTERN CAAnimationCalculationMode const kCAAnimationDiscrete
API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));//离散,无中间过程,但keyTimes设置的时间依旧生效,物体跳跃的出现在各个关键帧上
CA_EXTERN CAAnimationCalculationMode const kCAAnimationPaced
API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));//平均,keyTimes和Timing functions设置失效
CA_EXTERN CAAnimationCalculationMode const kCAAnimationCubic
API_AVAILABLE(macos(10.7), ios(4.0), watchos(2.0), tvos(9.0));//平均,同上
CA_EXTERN CAAnimationCalculationMode const kCAAnimationCubicPaced
API_AVAILABLE(macos(10.7), ios(4.0), watchos(2.0), tvos(9.0));//平均,同上
/* `rotationMode' strings. */
CA_EXTERN CAAnimationRotationMode const kCAAnimationRotateAuto
API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
CA_EXTERN CAAnimationRotationMode const kCAAnimationRotateAutoReverse
API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
示例
实现水波动画
- (void)drawRect:(CGRect)rect {
//新建动画数组
CALayer *animationLayer = [CALayer layer];
CAAnimationGroup *animationGroup = [self animationGroupAnimations:[self animationArray]];
CALayer *pulsingLayer = [self pulsingLayer:rect animationGroup:animationGroup];
//将动画 Layer 添加到 animationLayer
[animationLayer addSublayer:pulsingLayer];
// 新建缩放动画
CABasicAnimation *animationTwo = [self oppositeScaleAnimation];
// 新建一个动画 Layer,将动画添加上去
CALayer *pulsingLayerTwo = [self pulsingLayer:rect animation:animationTwo];
//将动画 Layer 添加到 animationLayer
[animationLayer addSublayer:pulsingLayerTwo];
[self.layer addSublayer:animationLayer];
}
- (CALayer *)pulsingLayer:(CGRect)rect animation:(CABasicAnimation *)animation {
CALayer *pulsingLayer = [CALayer layer];
pulsingLayer.borderWidth = 0.5;
pulsingLayer.borderColor = [[UIColor whiteColor]colorWithAlphaComponent:0.4].CGColor;
pulsingLayer.frame = CGRectMake(0, 0, rect.size.width, rect.size.height);
pulsingLayer.cornerRadius = rect.size.height / 2;
[pulsingLayer addAnimation:animation forKey:@"plulsing"];
return pulsingLayer;
}
- (CALayer *)pulsingLayer:(CGRect)rect animationGroup:(CAAnimationGroup *)animationGroup {
CALayer *pulsingLayer = [CALayer layer];
pulsingLayer.borderWidth = 1;
pulsingLayer.borderColor = [[UIColor whiteColor]colorWithAlphaComponent:0.4].CGColor;
pulsingLayer.frame = CGRectMake(0, 0, rect.size.width, rect.size.height);
pulsingLayer.cornerRadius = rect.size.height / 2;
[pulsingLayer addAnimation:animationGroup forKey:@"plulsing"];
return pulsingLayer;
}
- (CAAnimationGroup *)animationGroupAnimations:(NSArray *)array {
CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
animationGroup.beginTime = CACurrentMediaTime();
animationGroup.duration = 2;
animationGroup.repeatCount = 2;
animationGroup.autoreverses = YES;//动画结束时是否执行逆动画
animationGroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];//设置动画的速度变化:淡出
animationGroup.removedOnCompletion
return animationGroup;
}
- (NSArray *)animationArray {
NSArray *animationArray = nil;
CABasicAnimation *scaleAnimation = [self scaleAnimation];
CAKeyframeAnimation *borderColorAnimation = [self borderColorAnimation];
animationArray = @[scaleAnimation, borderColorAnimation];
return animationArray;
}
- (CABasicAnimation *)scaleAnimation {
CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
scaleAnimation.fromValue = @1;
scaleAnimation.toValue = @3;
return scaleAnimation;
}
- (CABasicAnimation *)oppositeScaleAnimation {
CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
scaleAnimation.fromValue = @1;
scaleAnimation.toValue = @0.7;
scaleAnimation.beginTime = CACurrentMediaTime();
scaleAnimation.duration = 2;
scaleAnimation.repeatCount = 2;
scaleAnimation.autoreverses = YES;//动画结束时是否执行逆动画
scaleAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];//设置动画的速度变化:淡出
return scaleAnimation;
}
- (CAKeyframeAnimation *)borderColorAnimation {
CAKeyframeAnimation *borderColorAnimation = [CAKeyframeAnimation animation];
borderColorAnimation.keyPath = @"borderColor";
borderColorAnimation.values = @[
(__bridge id)[[UIColor whiteColor]colorWithAlphaComponent:0.4].CGColor,
(__bridge id)[[UIColor whiteColor]colorWithAlphaComponent:0.3].CGColor,
(__bridge id)[[UIColor whiteColor]colorWithAlphaComponent:0.2].CGColor,
(__bridge id)[[UIColor whiteColor]colorWithAlphaComponent:0.1].CGColor,
(__bridge id)[[UIColor whiteColor]colorWithAlphaComponent:0.0].CGColor];
borderColorAnimation.keyTimes = @[@0.2,@0.4,@0.6,@0.8,@1
];
return borderColorAnimation;
}
引用、借鉴
iOS动画-CAAnimation使用详解https://www.jianshu.com/p/c22918a5e7ca
简书发表文章格式(MakrDwon使用)https://www.jianshu.com/p/0e63982d7a98