iOS 动画篇 - CAAnimation初识

CAAnimation是什么?

CAAnimation 是一个抽象动画类。 遵循并实现实现了 CAMediaTiming 和 CAAciotn 两个协议。 CAAnimation 无法直接使用,想要为 Core Animation 的图层或 Scene Kit 对象设置动画,应该使用其子类 CABasicAnimationCAKeyframeAnimationCAAnimationGroupCATransition 的实例。Core Animation可以用在 Mac OS X 和 iOS 平台。Core Animation 的动画执行过程都是在后台操作的,不会阻塞主线程。

注: 要注意的是,Core Animation是直接作用在图层上的,即 CALayer ,并非视图 UIView。当动画之行完毕,视图的 frame 并没有真实地改变。

认识 CAAnimation

  • CAAnimation 类中的常用属性,这些是有关动画效果的几个属性。
// 动画的节奏
@property(nullable, strong) CAMediaTimingFunction *timingFunction;
/*
系统给出的几种类型
 - kCAMediaTimingFunctionLinear //线性节奏,就是匀速
 - kCAMediaTimingFunctionEaseIn //淡入,缓慢加速进入,然后匀速
 - kCAMediaTimingFunctionEaseOut //淡出,匀速,然后缓慢减速移除
 - kCAMediaTimingFunctionEaseInEaseOut //淡入淡出,结合以上两者
 - kCAMediaTimingFunctionDefault //默认效果
*/

// 动画代理,注意该代理使用的是strong,注意释放问题
@property(nullable, strong) id  delegate;
// 开始和结束的代理
// 开始
-(void)animationDidStart:(CAAnimation *)anim;
// 结束、flag表示动画正常结束还是被打断移除
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;

// 是否在播放完成后移除,配合 fillMode = kCAFillModeForwards 可以保留最终的播放效果
@property(getter=isRemovedOnCompletion) BOOL removedOnCompletion;
  • CAMediaTiming 协议的定义的属性

该协议有关于动画时间相关的,例如开始结束的时间、重复时间等。

@property CFTimeInterval beginTime; // 动画开始时间(滞后时间)
@property CFTimeInterval duration; // 动画持续时间
@property float speed; // 速度 例:如果speed是2,duration是3,那么经过1.5秒,动画播放完成。
@property CFTimeInterval timeOffset; // 动画开始播放偏移时刻
@property float repeatCount; // 重复次数
@property CFTimeInterval repeatDuration; // 重复时间
@property BOOL autoreverses; // 自动执行相反动画
@property(copy) NSString *fillMode; // 播放结束后的状态
  • 使用步骤

1、初始化一个CAAnimation子类对象,设置一些动画相关属性;
2、通过调用CALayer的-addAnimation:forKey:方法增加CAAnimation对象到CALayer上
3、通过调用CALayer的-removeAnimationForKey:方法可以停止CALayer中的动画。

注:一个动画对象可以作用于多个视图,无需多次创建实例。

CABasicAnimation 基础动画

CABasicAnimation 可以看作是特殊的 CAKeyframeAnimation 动画,因为只需要指定一个初始状态和一个终止状态即可。

CABasicAnimation 是 CAPropertyAnimation 的子类,也叫属性动画,也就是针对视图的图层中的可动画属性进行动画操作,例如图层的位置 position、透明度 opacity 等,不是所有的属性都是可以进行动画的。

动画状态解析:

fromValue // 初始状态,即动画开始的状态点
toValue // 终止状态,即动画终止的状态点
byValue // 状态的增量

这三个值不能全为空,因为这样你就一个状态也没有指定。
也不能全不为空,因为这样你就指定了三个状态,系统也不知道选哪两个。
若果你指定了一个状态,那系统将自动以当前状态作为另一个状态。
若你指定了两个状态,则系统以这两个状态作为始末状态。
一般情况下,使用 fromValuetoValue 即可。

  • 使用示例:移动一个视图


    iOS 动画篇 - CAAnimation初识_第1张图片
    这里写图片描述
// …… 省略了视图部分
// 创建一个动画,针对视图位置 position 进行动画效果
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;
[testView.layer addAnimation:animation forKey:@"animation"]; //将动画添加到layer上
  • 可动画的属性一览

初始化中的 animationWithKeyPath 参数表示 layer 可进行动画的属性,一般常用的属性有以下多种。

KeyPath 说明 样例
transform.scale 缩放 @(0.5)
transform.scale.x 宽的比例 @(0.5)
transform.scale.y 宽的比例 @(0.5)
opacity 透明度 @(0.5)
cornerRadius 圆角 @(0.5)
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 valueWithCGRect:CGPointMake(100, 100)]
contents 显示的内容 (id)[UIImage imageNamed:@”imageName”].CGImage
  • 动画状态的监听

如果需要在动画执行的开始或者结束做点什么的时候,可以设置动画代理来完成状态监听。

- (void)animationDidStart:(CAAnimation *)anim{
    NSLog(@"动画开始");
}
// flag表明了动画是自然结束还是被打断,比如调用了removeAnimationForKey:方法,flag为NO,如果是正常结束,flag为YES。
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
    NSLog(@"%@",flag?@"自然结束":@"被系统或者人为结束");
}

注:此代理是 strong 强引用类型,需要手动置成 nil

CAKeyframeAnimation 关键帧动画

CAKeyframeAnimation 跟 CABasicAnimation 的区别是:CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue)。而 CAKeyframeAnimation 可以使用状态数组(关键帧数组)来展示不同的运动情况。

简单理解,CABasicAnimation 是针对两个状态的变化,CAKeyframeAnimation 是针对一组状态的变化。

CAKeyframeAnimation 是 CAPropertyAnimation 的子类,同样也是属性动画。

动画状态解析:

values //NSArray对象,里面的元素称为“关键帧” (keyframe)。动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧
path //让图层根据路径移动。Path只对CALayer的anchorPoint和position其作用。如果你设置了path,那么values将被忽略
keyTimes //对应的关键帧制定对应的时间点数组。其取值范围为0到1.0。如果没有设置,则关键帧平分duration
timingFunctions //对应关键帧制定对应的速率。

使用示例:


iOS 动画篇 - CAAnimation初识_第2张图片
这里写图片描述
// …… 省略layer部分
// 创建一个关键帧动画
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 对象添加到图层上后,组中所有动画对象可以同时并发运行。

CAAnimationGroup 是 CAAnimation 的子类。

属性解析:

animations // 存放并发执行的所有动画数组

注:

  1. 动画组中的动画不会被压缩,超出动画时长的部分将会被剪掉
  2. 动画组中的动画的 delegateremovedOnCompletion 属性将会被忽略 由于忽略了 removedOnCompletion 属性,动画结束图层会恢复到动画前的状态
  3. animations 存放并发执行的所有动画数组元素为CAAnimation的子类

CATransition 转场动画

CAAnimation 的子类,用于做转场动画,能够为图层提供移出屏幕和移入屏幕的动画效果。iOS 比 Mac OS X 的转场动画效果少一点。UINavigationController就是通过CATransition 实现了将控制器的视图推入屏幕的动画效果。

属性解析:

type //动画过渡类型:fade、moveIn、push、reveal。 默认fade
/*
  kCATransitionFade //交叉淡化过渡(不支持过渡方向)
  kCATransitionMoveIn //新视图移到旧视图上面 
  kCATransitionPush //新视图把旧视图推出去
  kCATransitionReveal //将旧视图移开,显示下面的新视图
*/
subtype //动画过渡方向
/* 过渡方向
  kCATransitionFromRight 
  kCATransitionFromLeft
  kCATransitionFromBottom 
  kCATransitionFromTop
*/
startProgress //动画起点(在整体动画的百分比)
endProgress //动画终点(在整体动画的百分比)

转场动画 type,除了系统给定的四种,还有私有的动画可以使用,不过只能使用字符串来设置。

  • cube //立方体翻滚效果
  • oglFlip //上下左右翻转效果
  • suckEffect //收缩效果,如一块布被抽走(不支持过渡方向)
  • rippleEffect //滴水效果(不支持过渡方向)
  • pageCurl //向上翻页效果
  • pageUnCurl //向下翻页效果
  • cameraIrisHollowOpen //相机镜头打开效果(不支持过渡方向)
  • cameraIrisHollowClose //相机镜头关上效果(不支持过渡方向)

使用示例


动画效果
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 弹性动画

CASpringAnimation 是 CABasicAnimation 基本动画的子类,在 iOS9 之后引入,可以实现弹性动画,例如篮球掉落,弹簧收缩。
CASpringAnimation 动画引入物理引擎,通过设置质量,阻尼系数等值模拟物体的弹性效果。

属性解析:

mass //质量,影响惯性、拉伸幅度
stiffness //刚度系数,刚度系数越大,形变产生的力就越大,运动越快
damping //阻尼系数,阻止弹簧伸缩的系数,阻尼系数越大,停止越快
CGFloat initialVelocity //初始速率  
settlingDuration //结算时间,可根据当前的动画参数估算弹簧动画到停止时的估算时间

使用示例


iOS 动画篇 - CAAnimation初识_第3张图片
小球落地效果
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地址

总结

CAAnimation 是一个抽象动画类,无法直接使用,需要使用它的子类,动画分为两大类:属性动画和转场动画。属性动画顾名思义,针对图层可动画属性进行动画,转场动画通常用于视图切换,例如A视图切换为B视图。CAAnimation 针对的是图层而非视图,因此默认情况下,它在完成动画后恢复到最初状态,且不会改变视图的相关属性。

拓展阅读

  • iOS 动画篇 - Core Animation

  • iOS 动画篇 - UIKit动画(一)

  • iOS 动画篇 - UIKit动画(二)

  • iOS 动画篇 - pop动画库

你可能感兴趣的:(iOS 动画篇 - CAAnimation初识)