CAKeyframeAnimation

认识CAKeyframeAnimation

CAKeyframeAnimation是可以在layer层按照一组关键帧执行的动画。它允许您在动画过程中设置一系列关键帧,每个关键帧定义了一个特定的属性值。这些关键帧之间通过插值算法生成平滑的动画效果。

属性介绍

1. keyPath: 动画的关键路径属性,用于指定要执行动画的属性。例如,如果您想要使一个视图在3秒内从左到右移动100像素,则可以将keyPath设置为“position”。

2. path: 基于点的属性的路径,对于包含CGPoint数据类型的层属性,您分配给该属性的路径对象定义了该属性在动画长度上的值。如果指定此属性的值,则忽略值属性中的任何数据。

3. values: 关键帧值表示动画必须执行的值。此属性中的值仅在path属性的值为nil时才使用。根据属性的类型,您可能需要用NSValue对象的NSNumber包装这个数组中的值。对于一些核心图形数据类型,您可能还需要将它们转换为id,然后再将它们添加到数组中。

4. duration: 动画时长,以秒为单位。

5. repeatCount: 重复次数,表示动画循环的次数。默认值为0,表示不重复。

6. calculationMode: 动画计算方式,用于控制关键帧之间的插值方法。有以下几种模式可供选择:

- kCAAnimationLinear(默认):线性插值,差值越大,动画越接近最后一个关键帧。

- kCAAnimationDiscrete:逐帧显示,动画会在每个关键帧之间断开。

- kCAAnimationPaced:匀速播放,无视keyTimes参数。

- kCAAnimationCubic:三次贝塞尔曲线插值,可以调整tensionValues、continuityValues和biasValues来改变曲线的形状。

- kCAAnimationCubicPaced:三次贝塞尔曲线插值,忽略keyTimes参数,使得关键帧之间的动画更平滑。

7. KeyTimes: 一个可选的NSNumber对象数组,它定义了给定关键帧片段的时间。默认情况下,所有关键帧的时间都是均匀分布的。

8. timingFunctions: 一个可选的CAMediaTimingFunction对象数组,它定义每个关键帧段的节奏。默认情况下,所有的timingFunction都是kCAMediaTimingFunctionLinear(线性起搏),即动画在其持续时间内均匀地发生。其他可用的timingFunction包括kCAMediaTimingFunctionEaseIn(使一个动画开始缓慢,然后加速)等。

以下是重构后的内容:

```markdown

kCAMediaTimingFunctionEaseOut:使动画快速开始,然后缓慢地进行。

kCAMediaTimingFunctionEaseInEaseOut:使动画开始缓慢,在其持续时间的中间加速,然后在完成之前再放慢速度。

kCAMediaTimingFunctionDefault:默认,确保动画的时间与大多数系统动画的匹配。

rotationMode:旋转方式。

kCAAnimationRotateAuto:自动旋转。

kCAAnimationRotateAutoReverse:自动翻转,不设置则不旋转。

示例:

```

```swift

import UIKit

import CoreGraphics

import QuartzCore

class Style1Button: UIButton {

var top: CAShapeLayer! = CAShapeLayer()

var bottom: CAShapeLayer! = CAShapeLayer()

var middle: CAShapeLayer! = CAShapeLayer()

// keyframe

let shortStrokeTop1 = UIBezierPath().then { (line) in

line.move(to: CGPoint(x: 10, y: 16))

line.addLine(to: CGPoint(x: 34, y: 16))

}

let shortStrokeTop2 = UIBezierPath().then { (line) in

line.move(to: CGPoint(x: 10, y: 17.5))

line.addLine(to: CGPoint(x: 30, y: 16))

}

let shortStrokeTop3 = UIBezierPath().then { (line) in

line.move(to: CGPoint(x: 10, y: 19))

line.addLine(to: CGPoint(x: 26, y: 17))

}

let shortStrokeTop4 = UIBezierPath().then { (line) in

line.move(to: CGPoint(x: 10, y: 20.5))

line.addLine(to: CGPoint(x: 22, y: 18))

}

let shortStrokeTop5 = UIBezierPath().then { (line) in

line.move(to: CGPoint(x: 10, y: 22))

line.addLine(to: CGPoint(x: 18, y: 19))

}

let shortStrokeBottom1 = UIBezierPath().then { (line) in

line.move(to: CGPoint(x: 10, y: 28))

line.addLine(to: CGPoint(x: 34, y: 28))

}

let shortStrokeBottom2 = UIBezierPath().then { (line) in

line.move(to: CGPoint(x: 10, y: 26.5))

line.addLine(to: CGPoint(x: 30, y: 28))

}

let shortStrokeBottom3 = UIBezierPath().then { (line) in

line.move(to: CGPoint(x: 10, y: 25))

line.addLine(to: CGPoint(x: 26, y: 27))

}

let shortStrokeBottom4 = UIBezierPath().then { (line) in

line.move(to: CGPoint(x: 10, y: 23.5))

line.addLine(to: CGPoint(x: 22, y: 26))

}

let shortStrokeBottom5 = UIBezierPath().then { (line) in

line.move(to: CGPoint(x))