首页 iOS开发:核心动画Core Animation
文章
取消

iOS开发:核心动画Core Animation

Core Animation的核心是图层(Layer),每个图层都是CALayer类的实例。与UIView相比,图层无法与用户直接交互,图层提供了更加底层的绘制和渲染功能,使得其能够高效地处理大量的视图对象。Core Animation还支持硬件加速,可以进一步提升性能。

除了提供基本的动画类型之外,Core Animation还提供了复杂的动画类型,比如关键帧动画、粒子效果等等。同时,Core Animation还支持图层变换、图层遮罩、高级绘制等功能,可以帮助开发者实现各种令人惊叹的界面效果。

核心概念

Core Animation 是一个基于 GPU 的动画框架,可以实现高性能的动画效果。其核心概念包括以下几个方面:

  • Layer:CALayer 是 Core Animation 的核心类之一,它是一个轻量级的对象,负责管理视图上的可见内容,并处理相关的动画和交互事件。
  • Property:每个 CALayer 都有一组属性,用于描述它的外观和行为。这些属性包括位置、大小、颜色、透明度、旋转等,可以通过动画来改变它们的值,从而实现动画效果。
  • Animation:CAAnimation 是 Core Animation 的另一个核心类,用于实现各种动画效果。它可以控制时间、速度、重复次数等参数,并可以与 CALayer 的属性关联起来,从而实现属性动画的效果。
  • Timing Function:CAMediaTimingFunction 是一个用于控制动画节奏的类,它可以指定不同的计时函数,例如线性、缓入缓出等,以控制动画的速度变化。
  • Group:CAAnimationGroup 是一个集合类,可以将多个动画组合在一起,从而实现同时或连续播放的效果。
  • Transform:CATransform3D 是一个矩阵变换类,用于实现 3D 动画效果。它可以控制平移、旋转、缩放等变换操作。
  • Emitter:CAEmitterLayer 是一个粒子系统类,可以创建各种粒子效果,例如雪花、火焰等。
  • Mask:CAShapeLayer 是一个图形层,可以定义各种形状的图形,用于遮罩或裁剪 CALayer 的内容。

动画类型

Core Animation 支持多种动画,以下是常见的几种动画类型:

  • 基础动画(CABasicAnimation):可以对 CALayer 的单个属性进行动画操作,例如位置、大小、透明度等。
  • 关键帧动画(CAKeyframeAnimation):可以定义多个关键帧来控制动画的行为,并在关键帧之间进行插值计算,以生成平滑过渡的效果。
  • 组合动画(CAAnimationGroup):可以将多个动画组合在一起,同时播放或顺序播放,从而实现复杂的动画效果。
  • 路径动画(CAKeyframeAnimation + CGPath):可以沿着指定的路径进行运动,从而实现曲线运动、圆弧运动等特殊效果。
  • 转场动画(CATransition):可以实现视图之间的过渡效果,例如淡入淡出、翻转、滑动等。
  • 逐帧动画(CAKeyframeAnimation + UIImage 数组):可以使用一组连续的图片来实现动画效果,例如动态图标、帧动画等。
  • 粒子系统动画(CAEmitterLayer):可以创建各种粒子效果,例如雪花、火焰等。
  • 视差滚动动画(CATransform3D + UIScrollView):可以实现视图的 3D 效果和视差滚动效果,例如卡片式翻页效果等。

Animation Timing

Core Animation 提供了多种动画时间函数(CAMediaTimingFunction),用于控制动画效果随时间的变化曲线。常见的动画时间函数包括:

  • kCAMediaTimingFunctionLinear:线性变化。
  • kCAMediaTimingFunctionEaseIn:慢进快出。
  • kCAMediaTimingFunctionEaseOut:快进慢出。
  • kCAMediaTimingFunctionEaseInEaseOut:慢进慢出。
  • kCAMediaTimingFunctionDefault:默认值,与 kCAMediaTimingFunctionEaseInEaseOut 相同。

我们可以使用 CAMediaTimingFunction 类的函数来创建自定义的时间函数,例如 initWithControlPoints:::: 方法,指定四个控制点的坐标,定制复杂的时间函数。

CALayer

CALayer 是 Core Animation 框架中最基本的类,它负责显示内容并处理与图层相关的任务。下面介绍一些常用的属性:

  • frame:图层的位置和大小(相对于父图层)。
  • bounds:图层的边界矩形,通常用于绘制或计算子图层的位置和大小。
  • position:图层中心点的坐标(相对于父图层)。
  • anchorPoint:锚点位置,范围是 (0, 0) 到 (1, 1),默认值是 (0.5, 0.5) 表示中心点。
  • transform:变换矩阵,可以实现平移、旋转、缩放等效果。
  • backgroundColor:背景色,可以是 UIColor 或 CGColorRef 对象。
  • cornerRadius:圆角半径,用于实现圆角矩形效果。
  • borderWidth 和 borderColor:边框宽度和颜色。
  • contents:图层的内容,可以是UIImage、CGImageRef、UIView 等对象。
  • contentsGravity:内容对齐方式,例如 kCAGravityCenter、kCAGravityTop 等。
  • contentsScale:内容缩放比例,通常设置为屏幕的缩放比例。
  • masksToBounds:是否裁剪超出边界的部分,用于实现圆形图像等效果。
  • opacity:不透明度,取值范围是 0.0 到 1.0。
  • shadowColor、shadowOffset、shadowOpacity、shadowRadius:阴影效果的相关属性。

绘制图形

CALayer 本身不具备绘制能力,但是可以通过以下几种方式绘制图形:

  • 使用 contents 属性,将图像作为 layer 的内容显示。
  • 使用 drawRect: 方法,在 layer 上手动绘制图形,需要自己管理上下文和绘制命令。
  • 使用 CAShapeLayer 类,绘制矢量图形,可以使用 UIBezierPath 等类创建路径。

动画效果

  • addAnimation:forKey: 方法:为 layer 添加动画效果。
  • removeAnimationForKey: 方法:移除指定 key 的动画效果。
  • removeAllAnimations 方法:移除所有的动画效果。
  • animationKeys 方法:返回当前 layer 所有动画效果的 key。
  • animationForKey: 方法:返回指定 key 的动画对象。

CALayer高阶应用

Masking and Clipping Layers

CALayer 支持遮罩(masking)和裁剪(clipping)功能,用于显示图层的部分区域。常见的方式包括:

  • mask:设置遮罩图层,只有遮罩图层中的不透明部分才会显示出来。
  • masksToBounds:是否裁剪超出边界的部分,用于实现圆形图像等效果。
  • contentsRect:指定 layer 显示区域,可用于裁剪图像或者显示图片集合中的某个部分。
  • drawInContext: 方法:可以手动绘制遮罩或裁剪区域。

Layer Effects

CALayer 支持许多视觉效果,例如模糊效果、圆角效果、倒影效果等。我们可以通过设置 CALayer 的属性来实现这些效果。常见的效果包括:

  • cornerRadius:圆角半径,用于实现圆角矩形效果。
  • borderWidth 和 borderColor:边框宽度和颜色。
  • shadowColor、shadowOffset、shadowOpacity、shadowRadius:阴影效果的相关属性。
  • filters:滤镜效果,例如 CIGaussianBlur、CIColorMonochrome 等。

Layer Transforms

CALayer 支持变换矩阵(transform)属性,用于实现平移、旋转、缩放等效果。常见的变换属性包括:

  • transform:变换矩阵,可以实现平移、旋转、缩放等效果。
  • affineTransform 方法:用于获取当前变换矩阵的 CGAffineTransform 对象,方便在其他地方使用。
  • CATransform3DMakeRotation、CATransform3DMakeTranslation、CATransform3DMakeScale 等方法:用于创建 CATransform3D 对象,方便在变换过程中使用。

示例

  • 添加阴影效果

下面这段代码创建了一个大小为 100x100 的红色图层,并为其添加了一个黑色、偏移量为 (0, 5)、透明度为 0.5、半径为 5 的阴影效果。

1
2
3
4
5
6
7
8
CALayer *layer = [[CALayer alloc] init];
layer.frame = CGRectMake(50, 50, 100, 100);
layer.backgroundColor = [UIColor redColor].CGColor;
layer.shadowColor = [UIColor blackColor].CGColor;
layer.shadowOffset = CGSizeMake(0, 5);
layer.shadowOpacity = 0.5;
layer.shadowRadius = 5;
[self.view.layer addSublayer:layer];
  • 实现自定义渐变背景色

下面这段代码创建了一个 CAGradientLayer 对象,并将其添加到了当前 view 的 layer 上。首先设置了 gradientLayer 的 frame 属性,然后设置了 startPoint 和 endPoint 属性来指定渐变方向。最后设置 colors 属性为一个包含三个 CGColorRef 对象的 NSArray,从而实现渐变色的效果。

1
2
3
4
5
6
7
8
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = self.view.bounds;
gradientLayer.startPoint = CGPointMake(0, 0);
gradientLayer.endPoint = CGPointMake(1, 1);
gradientLayer.colors = @[(__bridge id)[UIColor redColor].CGColor,
                         (__bridge id)[UIColor yellowColor].CGColor,
                         (__bridge id)[UIColor greenColor].CGColor];
[self.view.layer addSublayer:gradientLayer];

CAShapeLayer

CAShapeLayer 是 Core Animation 中的一个图层类,它是 CALayer 的子类之一。CAShapeLayer 可以用于绘制矢量图形,例如线条、多边形、圆弧等,并可以为这些形状添加填充、描边等样式。

与常规的绘图方式不同,CAShapeLayer 使用矢量路径来定义形状,而不是使用像素点直接绘制图像。

常用属性

  • path:要绘制的路径,可以是 UIBezierPath 或者 CGPathRef 对象。
  • fillColor:填充颜色,可以是 UIColor 或 CGColorRef 对象。
  • strokeColor:描边颜色,可以是 UIColor 或 CGColorRef 对象。
  • lineWidth:线宽。
  • lineDashPattern:虚线样式,数组中存储着线条和间隙的长度值。
  • lineCap:线端点样式,例如 kCALineCapButt、kCALineCapRound 等。
  • lineJoin:线交汇处样式,例如 kCALineJoinMiter、kCALineJoinRound 等。
  • miterLimit:斜角尺寸超过这个值就使用 lineJoin 样式中的 kCALineJoinMiter 样式,否则使用 kCALineJoinBevel 样式。

绘制方法

CAShapeLayer 一般配合 UIBezierPath 使用,下面介绍几种绘制方法:

  • addSublayer: 方法:将 CAShapeLayer 添加到父图层。
  • setNeedsDisplay 方法:标记图层需要重新渲染,此时会调用 drawInContext: 方法进行绘制。
  • stroke 方法:绘制描边路径。
  • fill 方法:填充路径。
  • addArcWithCenter:radius:startAngle:endAngle:clockwise: 方法:绘制圆弧。

示例

  • 实现圆形进度条动画

下面这段代码创建了一个 CAShapeLayer 对象,用于实现一个圆形进度条动画。首先绘制出一个圆形路径,然后将 strokeEnd 的属性值从 0.0 缓慢过渡到 1.0,从而实现进度条的增长效果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CAShapeLayer *progressLayer = [CAShapeLayer layer];
progressLayer.frame = CGRectMake(0, 0, 100, 100);
progressLayer.lineWidth = 10.0;
progressLayer.fillColor = [UIColor clearColor].CGColor;
progressLayer.strokeColor = [UIColor redColor].CGColor;
progressLayer.strokeStart = 0.0;
progressLayer.strokeEnd = 0.0;
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:progressLayer.bounds];
progressLayer.path = path.CGPath;
[self.view.layer addSublayer:progressLayer];

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
animation.duration = 2.0;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.fromValue = @(0.0);
animation.toValue = @(1.0);
animation.delegate = self;
[progressLayer addAnimation:animation forKey:@"strokeEndAnimation"];

CATextLayer

CATextLayer 是 Core Animation 中的一个图层类,它是 CALayer 的子类之一。CATextLayer 可以用于在图层中绘制文本,并可以设置字体、颜色、对齐方式等样式。

与常规的文本绘制方式不同,CATextLayer 使用 Core Text 技术来渲染文本。

常用属性

  • string:显示的文本内容。
  • fontSize:字体大小。
  • font:字体名称和大小,例如 @”HelveticaNeue-Bold”、@”ArialMT” 等。
  • foregroundColor:前景色,可以是 UIColor 或 CGColorRef 对象。
  • alignmentMode:对齐方式,例如 kCAAlignmentLeft、kCAAlignmentCenter 等。
  • truncationMode:截断方式,例如 kCATruncationEnd、kCATruncationMiddle 等。
  • wrapped:是否自动换行,默认为 NO。
  • contentsScale:内容缩放比例,通常设置为屏幕的缩放比例。

绘制方法

CATextLayer 可以通过以下方法进行绘制:

  • addSublayer: 方法:将 CATextLayer 添加到父图层。
  • setNeedsDisplay 方法:标记图层需要重新渲染,此时会调用 drawInContext: 方法进行绘制。

示例

  • 在界面上显示富文本

下面这段代码创建了一个 CATextLayer 对象,并将其添加到了当前 view 的 layer 上。首先设置了 textLayer 的 frame 属性,然后设置了 string 属性为一个 NSMutableAttributedString 对象。通过使用 NSMutableAttributedString 实现富文本效果,其中前五个字符的字体颜色设为红色,第七个字符到第十二个字符的背景颜色设为黄色,同时加上下划线的效果。

1
2
3
4
5
6
7
8
9
10
CATextLayer *textLayer = [CATextLayer layer];
textLayer.frame = CGRectMake(50, 50, 200, 100);
textLayer.string = ({
    NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:@"Hello World!"];
    [string addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, 5)];
    [string addAttribute:NSBackgroundColorAttributeName value:[UIColor yellowColor] range:NSMakeRange(6, 6)];
    [string addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:NSMakeRange(6, 6)];
    string;
});
[self.view.layer addSublayer:textLayer];

CABasicAnimation

CABasicAnimation 类表示基本动画,它可以对任何可动画属性进行操作,包括 CALayer 和 UIView 的大部分属性。下面介绍一些常用的属性:

  • fromValue 和 toValue:指定动画的起始值和结束值。
  • byValue:指定动画增加的值,与 toValue 二选一使用。
  • duration:动画时长。
  • repeatCount:重复次数,默认只播放一次。
  • autoreverses:是否自动倒播动画,即从目标值返回到初始值。
  • timingFunction:动画时间函数,控制动画效果随时间的变化曲线。
  • fillMode:动画结束后的行为,通常设为 kCAFillModeForwards,保持动画结束状态。

示例

  • 实现一个简单的旋转动画

下面这段代码创建了一个 CABasicAnimation 对象,用于实现一个以 Z 轴为中心的无限旋转动画。在动画结束前,它会不断重复执行。

1
2
3
4
5
6
CABasicAnimation* rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
rotationAnimation.toValue = [NSNumber numberWithFloat:M_PI * 2.0];
rotationAnimation.duration = 1.0;
rotationAnimation.cumulative = YES;
rotationAnimation.repeatCount = HUGE_VALF;
[self.view.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];
  • 实现一个立体翻转动画

下面这段代码创建了一个 UIView 对象,并为其添加了一个立体翻转的效果。首先创建了一个 CATransform3D 对象,通过设置 m34 属性来实现透视效果。然后创建了一个 CABasicAnimation 对象,用于实现动画效果,从而让 view 翻转到 180 度的角度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 100, 100)];
view.backgroundColor = [UIColor redColor];
[self.view addSubview:view];

CATransform3D transform = CATransform3DIdentity;
transform.m34 = -1.0 / 500.0;

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
animation.duration = 2.0;
animation.fromValue = @(0);
animation.toValue = @(M_PI);
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

view.layer.anchorPoint = CGPointMake(0, 0.5);
view.layer.transform = transform;
[view.layer addAnimation:animation forKey:@"flipAnimation"];

CAKeyframeAnimation

CAKeyframeAnimation 类表示关键帧动画,它可以指定多个关键帧,让 Core Animation 自动计算中间的过渡动画。下面介绍一些常用的属性:

  • values:指定关键帧动画的多个值。
  • keyTimes:指定每个关键帧对应的时间点。
  • path:指定动画路径,可以是一个 UIBezierPath 对象或者 CGPathRef 对象。
  • calculationMode:指定关键帧之间的计算模式,例如线性、均匀等。
  • rotationMode:指定旋转方式,例如沿着路径旋转等。

示例

  • 实现贝塞尔曲线动画

下面这段代码创建了一个 CAKeyframeAnimation 对象添加到红色方块上,用于实现一段贝塞尔曲线动画。红色方块会沿着这条曲线移动。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
UIView *redSquare = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 50, 50)];
redSquare.backgroundColor = [UIColor redColor];
[self.view addSubview:redSquare];

CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
animation.duration = 2.0;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, 25, 25);
CGPathAddCurveToPoint(path, NULL, 225, 25, 225, 175, 25, 175);
CGPathAddLineToPoint(path, NULL, 25, 275);
animation.path = path;
CGPathRelease(path);

[redSquare.layer addAnimation:animation forKey:@"positionAnimation"];
  • 实现一段弹簧效果动画

下面这段代码创建了一个 CASpringAnimation 对象,用于实现一段弹簧效果动画。动画的开始和结束位置设置了一个水平方向上的偏移量,然后通过调整质量、刚度、阻尼和初速度等参数,实现了仿佛在弹簧上运动的动画效果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
UIView *redSquare = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 50, 50)];
redSquare.backgroundColor = [UIColor redColor];
[self.view addSubview:redSquare];

CASpringAnimation *animation = [CASpringAnimation animationWithKeyPath:@"position.x"];
animation.duration = animation.settlingDuration;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.mass = 2.0;
animation.stiffness = 200.0;
animation.damping = 10.0;
animation.initialVelocity = 0.0;
animation.fromValue = @(self.view.center.x - 50);
animation.toValue = @(self.view.center.x + 50);

[redSquare.layer addAnimation:animation forKey:@"positionAnimation"];

CAEmitterLayer

CAEmitterLayer 是一个高效的粒子系统(particle system)实现类。使用 CAEmitterCell 对象作为源,可以创建各种不同类型的粒子效果,例如烟花、雨滴、火焰等。

常用属性

  • emitterCells:粒子源数组。
  • birthRate:每秒产生的粒子数量。
  • lifetime:粒子存活时间。
  • emitterPosition 和 emitterZPosition:发射器位置和深度。
  • emitterSize 和 emitterDepth:发射器大小和深度。
  • velocity 和 velocityRange:粒子速度及其范围。
  • scale 和 scaleRange:粒子缩放比例及其范围。
  • spin 和 spinRange:粒子自旋及其范围。
  • color 和 colorRange:粒子颜色及其范围。
  • alphaSpeed:透明度变化速度。
  • contents:粒子内容,可以是 UIImage、CGImageRef、UIView 等对象。

绘制方法

CAEmitterLayer 可以通过以下方法进行绘制:

  • addSublayer: 方法:将 CAEmitterLayer 添加到父图层。
  • setNeedsDisplay 方法:标记图层需要重新渲染,此时会调用 drawInContext: 方法进行绘制。

示例

  • 实现雪花效果

下面这段代码创建了一个 CAEmitterLayer 对象,用于实现雪花效果的粒子系统。首先指定了粒子发射器的形状、位置、大小、产生速率和寿命等属性,然后创建一个 CAEmitterCell 对象,设置其内容为雪花图片,再设置了其缩放、速度、发射方向和角度等属性。最后将这个 cell 对象添加到 emitterLayer 的 emitterCells 数组中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
CAEmitterLayer *emitterLayer = [CAEmitterLayer layer];
emitterLayer.frame = self.view.bounds;
emitterLayer.emitterShape = kCAEmitterLayerLine;
emitterLayer.emitterPosition = CGPointMake(emitterLayer.frame.size.width / 2, -20);
emitterLayer.emitterSize = CGSizeMake(emitterLayer.frame.size.width, 1);
emitterLayer.birthRate = 5;
emitterLayer.lifetime = 20;

CAEmitterCell *cell = [CAEmitterCell emitterCell];
UIImage *image = [UIImage imageNamed:@"image.png"];
cell.contents = (__bridge id)(image.CGImage);
cell.color = [UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:1.0].CGColor;
cell.scale = 0.2;
cell.scaleRange = 0.5;
cell.velocity = 50;
cell.velocityRange = 100;
cell.emissionLongitude = M_PI;
cell.emissionRange = M_PI_4;
cell.spin = 2 * M_PI;
cell.spinRange = 2 * M_PI;
cell.birthRate = 1;
cell.lifetime = 10;

emitterLayer.emitterCells = @[cell];
[self.view.layer addSublayer:emitterLayer];
  • 实现火焰效果

下面这段代码创建了一个 CAEmitterLayer 对象,用于实现火焰效果的粒子系统。同样指定了粒子发射器的形状、位置、大小、产生速率和寿命等属性,然后创建一个 CAEmitterCell 对象,设置其内容为火焰图片,再设置了其颜色、缩放、透明度、速度、发射方向和角度等属性。最后将这个 cell 对象添加到 emitterLayer 的 emitterCells 数组中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
CAEmitterLayer *emitterLayer = [CAEmitterLayer layer];
emitterLayer.frame = self.view.bounds;
emitterLayer.emitterShape = kCAEmitterLayerPoint;
emitterLayer.emitterPosition = CGPointMake(emitterLayer.frame.size.width / 2, emitterLayer.frame.size.height - 50);
emitterLayer.emitterSize = CGSizeMake(30, 0);
emitterLayer.birthRate = 100;
emitterLayer.lifetime = 1;

CAEmitterCell *cell = [CAEmitterCell emitterCell];
UIImage *image = [UIImage imageNamed:@"image.png"];
cell.contents = (__bridge id)(image.CGImage);
cell.color = [[UIColor colorWithRed:1 green:0.5 blue:0.2 alpha:1] CGColor];
cell.scale = 0.3;
cell.scaleRange = 0.1;
cell.scaleSpeed = -0.2;
cell.alphaRange = 0.5;
cell.alphaSpeed = -0.2;
cell.velocity = 80;
cell.velocityRange = 40;
cell.emissionLongitude = -M_PI_2;
cell.emissionRange = M_PI_4;
cell.spin = 2 * M_PI;
cell.spinRange = 2 * M_PI;
cell.birthRate = 1;
cell.lifetime = 2;

emitterLayer.emitterCells = @[cell];
[self.view.layer addSublayer:emitterLayer];

CAAnimationGroup

CAAnimationGroup 类表示组合动画,它可以将两个或多个动画组合成一个组,同时运行。下面介绍一些常用的属性:

  • animations:指定要组合的动画数组。
  • duration:总共的动画时长。
  • repeatCount:重复次数,默认只播放一次。
  • autoreverses:是否自动倒播动画,即从目标值返回到初始值。
  • timingFunction:动画时间函数,控制动画效果随时间的变化曲线。
  • fillMode:动画结束后的行为,通常设为 kCAFillModeForwards,保持动画结束状态。

示例

实现多个动画同时执行。下面这段代码创建了一个 UIView 对象,并同时为其添加了缩放和透明度变化两个动画效果。首先创建了两个 CABasicAnimation 对象,分别用于实现缩放和透明度变化的效果。然后创建了一个 CAAnimationGroup 对象,并将两个 CABasicAnimation 对象包装在里面,通过设置 animations 属性将它们同时执行。最后将 CAAnimationGroup 对象添加到 view 的 layer 上,从而让两个动画同时生效。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 100, 100)];
view.backgroundColor = [UIColor redColor];
[self.view addSubview:view];

CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
scaleAnimation.duration = 2.0;
scaleAnimation.fromValue = @(1);
scaleAnimation.toValue = @(0.5);

CABasicAnimation *opacityAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
opacityAnimation.duration = 2.0;
opacityAnimation.fromValue = @(1);
opacityAnimation.toValue = @(0);

CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
animationGroup.animations = @[scaleAnimation, opacityAnimation];
animationGroup.duration = 2.0;

view.layer.anchorPoint = CGPointMake(0.5, 0.5);
[view.layer addAnimation:animationGroup forKey:@"groupAnimation"];

Metal and OpenGL

Core Animation 支持使用 Metal 和 OpenGL 进行图形渲染,可以实现更加复杂的图像效果。Metal 是苹果公司推出的 GPU 编程接口,它可以与 Core Animation 配合使用,高效地对图像进行处理。OpenGL 是一种跨平台的图形渲染 API,同样可以与 Core Animation 配合使用,支持多种平台和设备。

使用 Metal 或 OpenGL 需要先创建一个 CALayer,然后将其设置为 MetalView 或 GLKView 的 layer 属性,然后通过编写相应的渲染代码实现图形渲染。

Remote Display of Layer Content

Core Animation 支持将图层内容通过网络传输到其他设备上显示。这个功能被称为远程显示(remote display),它使用了 AirPlay 技术来实现。

要使用远程显示功能,需要满足以下条件:

  • 手机或者电脑需要连接到同一个 WiFi 网络。
  • 接收端也需要支持 AirPlay 功能。

在 iOS 中,可以通过设置 AVPlayerLayer 或 AVSampleBufferDisplayLayer 的 allowsExternalPlayback 属性来开启远程显示功能。在 Mac OS X 中,可以通过设置 NSWindow 的 allowsAutomaticWindowTabbing 属性来开启远程显示功能。

显式动画和隐式动画

Core Animation支持两种动画:显式动画和隐式动画。

显式动画是通过手动指定动画效果来触发的,比如我们前面介绍的CABasicAnimation、CAKeyframeAnimation等类。

隐式动画是当图层的可动画属性值发生变化时,自动触发的动画效果。每个CALayer对象都有一组默认的可动画属性(也就是支持隐式动画的属性),比如position、bounds、backgroundColor等。当这些属性值发生变化时,默认会自动触发相应的动画效果,持续时间0.25秒左右,并且有一个默认的动画效果(CATransaction默认的timing function)。

隐式动画相对于显式动画来说,代码量更少,易于管理和维护,但是其动画效果相对固定,无法实现复杂的动画效果。

我们可以通过调用CATransaction的方法来控制隐式动画的行为。比如我们可以关闭隐式动画:

1
2
3
4
[CATransaction begin];
[CATransaction setDisableActions:YES]; // 关闭隐式动画
layer.position = CGPointMake(100, 100);
[CATransaction commit];

或者自定义隐式动画的持续时间和timing function:

1
2
3
4
5
[CATransaction begin];
[CATransaction setAnimationDuration:2.0];
[CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
layer.position = CGPointMake(100, 100);
[CATransaction commit];
本文由作者按照 CC BY 4.0 进行授权

iOS开发:动画UIView Animation

iOS开发:物理引擎UIKit Dynamics