动画篇----CAAnimation
一、CAAnimation是什么
1、官方解释:
CAAnimation is an abstract animation class. It provides the basic support for the CAMediaTiming and CAAction protocols. To animate Core Animation layers or Scene Kit objects, create instances of the concrete subclasses CABasicAnimation, CAKeyframeAnimation, CAAnimationGroup, or CATransition.
CAAnimation是一个抽象动画类。 遵循着CAMediaTiming和CAAciotn两个协议。 要为Core Animation图层或Scene Kit对象设置动画,请创建其子类CABasicAnimation,CAKeyframeAnimation,CAAnimationGroup或CATransition的实例。Core Animation可以用在Mac OS X和iOS平台。Core Animation的动画执行过程都是在后台操作的,不会阻塞主线程。
注: 要注意的是,Core Animation是直接作用在CALayer上的,并非UIView。当动画之行完毕,控件的frame并没有改变。
2、基类CAAnimation的几种属性
// 动画的节奏
/*
系统给出的几种类型
- kCAMediaTimingFunctionLinear//线性节奏,就是匀速
- kCAMediaTimingFunctionEaseIn//淡入,缓慢加速进入,然后匀速
- kCAMediaTimingFunctionEaseOut//淡出,匀速,然后缓慢减速移除
- kCAMediaTimingFunctionEaseInEaseOut//淡入淡出,结合以上两者
- kCAMediaTimingFunctionDefault//默认效果
*/
@property(nullable, strong) CAMediaTimingFunction *timingFunction;
// 动画代理,注意该代理使用的是strong,注意释放
@property(nullable, strong) id <CAAnimationDelegate> delegate;
// 开始和结束的代理
// 开始
-(void)animationDidStart:(CAAnimation *)anim;
// 结束、flag表示动画正常结束还是被打断移除
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
// 是否在播放完成后移除,配合fillMode = kCAFillModeForwards可以保留最终的播放效果
@property(getter=isRemovedOnCompletion) BOOL removedOnCompletion;
3、CAMediaTiming协议中的相关属性
// 动画开始时间(滞后时间)
@property CFTimeInterval beginTime;
// 动画持续时间
@property CFTimeInterval duration;
// 速度 例:如果speed是2,duration是3,那么经过1.5秒,动画播放完成。
@property float speed;
// 动画开始播放偏移时刻
@property CFTimeInterval timeOffset;
// 重复次数
@property float repeatCount;
// 重复时间
@property CFTimeInterval repeatDuration;
// 自动执行相反动画
@property BOOL autoreverses;
// 播放结束后的状态
@property(copy) NSString *fillMode;
4、使用步骤
注:CAAnimation是一个抽象类,想要实现动画效果需要使用它的子类CABasicAnimation,CAKeyframeAnimation,CAAnimationGroup或CATransition。
使用步骤:
1.添加QuartzCore.framework框架和引入主头文件<QuartzCore/QuartzCore.h>(iOS7不需要);
2.初始化一个CAAnimation对象,并设置一些动画相关属性;
3.通过调用CALayer的addAnimation:forKey:方法增加CAAnimation对象到CALayer中
4.通过调用CALayer的removeAnimationForKey:方法可以停止CALayer中的动画。
二、CABasicAnimation基本动画
CABasicAnimation可以看作是特殊的CAKeyframeAnimation动画,因为只需要指定一个初始状态和一个终止状态即可。
CAPropertyAnimation的子类.属性解析:
fromValue就是指定初始状态
toValue就是终止状态
byValue就是状态的增量
这三个值不能全为空,因为这样你就一个状态也没有指定。
也不能全不为空,因为这样你就指定了三个状态,系统也不知道选哪两个。
若果你指定了一个状态,那系统将自动以当前状态作为另一个状态。
若你指定了两个状态,则系统已这两个状态作为始末状态。
使用示例:移动一个视图
<center>
// 创建一个View
UIView *testView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 100)];
testView.center = self.view.center;
testView.backgroundColor = [UIColor redColor];
[self.view addSubview:testView];
// 创建一个动画
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
animation.duration = 1.0f; // 动画之行时间
animation.toValue = [NSValue valueWithCGPoint:CGPointMake(0, 0)]; // 移动到新的位置
animation.beginTime = CACurrentMediaTime() + 0; // 延迟
animation.autoreverses = YES; // 动画结束时是否执行逆动画
animation.repeatCount = HUGE_VALF; // 重复次数(无限大)
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; // 速度
// animation.removedOnCompletion = NO;
// animation.fillMode = kCAFillModeForwards;
// 将动画添加到layer上
[testView.layer addAnimation:animation forKey:@"animation"];
注:
1、初始化中的“animationWithKeyPath“所带的字符串表示需要修改的layer属性,一般常用的属性如下:
/*
常用的KeyPath
key 说明 使用样例
transform.scale 缩放 @(0.5)
transform.scale.x 宽的比例 @(0.5)
transform.scale.y 高的比例 @(0.5)
opacity 透明度 @(0.5)
cornerRadius 圆角的设置 @(50)
transform.rotation.x 围绕x轴旋转 @(M_PI)
transform.rotation.y 围绕y轴旋转 @(M_PI)
transform.rotation.z 围绕z轴旋转 @(M_PI)
strokeStart 结合CAShapeLayer使用 赋值多变
strokeEnd 结合CAShapeLayer使用 赋值都变
bounds 大小,中心不变 [NSValue valueWithCGRect:CGRectMake(0, 0, 100, 100)];
position 位置(中心点的改变) [NSValue valueWithCGPoint:CGPointMake(100, 100)];
contents 内容, 比如UIImageView的图片 imageAnima.toValue = (id)[UIImage imageNamed:@”imageName”].CGImage;
*/
2、如果需要在动画执行的开始或者结束做点什么的时候,可以使用CAAnimationDelegate的代理协议来完成
#pragma mark - CAAnimation代理方法
- (void)animationDidStart:(CAAnimation *)anim{
NSLog(@"开始了");
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
//方法中的flag参数表明了动画是自然结束还是被打断,比如调用了removeAnimationForKey:方法或removeAnimationForKey方法,flag为NO,如果是正常结束,flag为YES。
NSLog(@"%@",flag?@"自然结束":@"被人为结束");
}
注:此代理是strong类型,需要手动nil。
三、CAKeyframeAnimation关键帧动画
CAKeyframeAnimation跟ABasicAnimation的区别是:CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue).而CAKeyframeAnimation 可以使用状态数组(关键帧数组)来展示不同的运动情况。
CAPropertyAnimation的子类.属性解析:
// NSArray对象,里面的元素称为“关键帧” (keyframe)。动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧。
@property(nullable, copy) NSArray *values;
// 可以设置一个CGPathRef \ CGMutablePathRef,让层跟着路径移动.。Path只对CALayer的anchorPoint和position其作用。如果你设置了path,那么values将被忽略。
@property(nullable) CGPathRef path;
// 对应的关键帧制定对应的时间点数组。其取值范围为0到1.0。如果没有设置,则关键帧平分duration。
@property(nullable, copy) NSArray<NSNumber *> *keyTimes;
// timingFunctions:对应关键帧制定对应的速率。
@property(nullable, copy) NSArray<CAMediaTimingFunction *> *timingFunctions;
使用示例:
<center>
// 创建一个CALayer对象
CALayer *testLayer = [CALayer layer];
testLayer.frame = CGRectMake(15, 200, 30, 30);
testLayer.cornerRadius = _testLayer.frame.size.height/2.0;
testLayer.backgroundColor = [UIColor redColor].CGColor;
[self.view.layer addSublayer:testLayer];
// 创建一个关键帧动画
CAKeyframeAnimation *aniByValues = [CAKeyframeAnimation animationWithKeyPath:@"position"];
aniByValues.duration = 3.0f;
aniByValues.repeatCount = HUGE_VALF;
// 设置关键帧位置数组
aniByValues.values = @[[NSValue valueWithCGPoint:testLayer.position],[NSValue valueWithCGPoint:CGPointMake(kScreenWidth-30, testLayer.frame.origin.y)],[NSValue valueWithCGPoint:CGPointMake(kScreenWidth-30, testLayer.frame.origin.y+100)],[NSValue valueWithCGPoint:CGPointMake(30, testLayer.frame.origin.y+100)],[NSValue valueWithCGPoint:testLayer.position],];
// 添加
[testLayer addAnimation:aniByValues forKey:@"position"];
四、CAAnimationGroup动画组
可以保存一组动画对象,将CAAnimationGroup对象加入层后,组中所有动画对象可以同时并发运行。
CAAnimation的子类,属性解析:
// 存放并发执行的所有动画数组
@property(nullable, copy) NSArray<CAAnimation *> *animations;
注:
1、动画组中的动画不会被压缩,超出动画时长的部分将会被剪掉
2、动画组中的动画的delegate与removedOnCompletion属性将会被忽略 由于忽略了removedOnCompletion属性,动画结束layer会恢复到动画前的状态
3、animations(NSArray *)存放并发执行的所有动画数组元素为CAAnimation的子类
四、CATransition转场动画
CAAnimation的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。iOS比Mac OS X的转场动画效果少一点。UINavigationController就是通过CATransition实现了将控制器的视图推入屏幕的动画效果。
属性解析:
// 动画过渡类型
// fade、moveIn、push、reveal。 默认fade
@property(copy) NSString *type;
// 动画过渡方向
/* 过渡方向
kCATransitionFromRight
kCATransitionFromLeft
kCATransitionFromBottom
kCATransitionFromTop
*/
@property(nullable, copy) NSString *subtype;
// 动画起点(在整体动画的百分比)
@property float startProgress;
// 动画终点(在整体动画的百分比)
@property float endProgress;
注:
1、type,除了系统给定的四种,即
- kCATransitionFade // 交叉淡化过渡(不支持过渡方向)
- kCATransitionMoveIn // 新视图移到旧视图上面
- kCATransitionPush // 新视图把旧视图推出去
- kCATransitionReveal // 将旧视图移开,显示下面的新视图
还有私有的动画可以使用,不过只能使用字符串来设置
- cube //立方体翻滚效果
- oglFlip //上下左右翻转效果
- suckEffect //收缩效果,如一块布被抽走(不支持过渡方向)
- rippleEffect //滴水效果(不支持过渡方向)
- pageCurl //向上翻页效果
- pageUnCurl //向下翻页效果
- cameraIrisHollowOpen //相机镜头打开效果(不支持过渡方向)
- cameraIrisHollowClose //相机镜头关上效果(不支持过渡方向)
使用示例:
<center>
CATransition *transition = [CATransition animation];
transition.type = @"cube"; // 动画过渡类型
transition.subtype = kCATransitionFromRight; // 动画过渡方向
transition.duration = 1; // 动画持续1s
[self.imageView.layer addAnimation:transition forKey:@"KCATransitionAnimation"];
使用场景:imageView切换图片,控制器的push或modal方法等
五、CASpringAnimation弹性动画
CABasicAnimation基本动画的子类,可以实现弹性动画
属性解析:
// 质量,影响惯性、拉伸幅度
@property CGFloat mass;
// 刚度系数,刚度系数越大,形变产生的力就越大,运动越快
@property CGFloat stiffness;
// 阻尼系数,阻止弹簧伸缩的系数,阻尼系数越大,停止越快
@property CGFloat damping;
// 初始速率
@property CGFloat initialVelocity;
// 结算时间 根据当前的动画参数估算弹簧动画到停止时的估算时间
@property(readonly) CFTimeInterval settlingDuration;
使用示例:
<center>
CASpringAnimationa *animation = [CASpringAnimation animationWithKeyPath:@"position.y"];
animation.damping = 5; // 阻尼系数
animation.stiffness = 100; // 刚度系数
animation.mass = 1; // 质量
animation.initialVelocity = 0; // 初始速率
animation.duration = animation.settlingDuration; //结束时间
animation.fromValue = @(self.layer.position.y);
animation.toValue = @(self.layer.position.y+100);
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
六、demo地址