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))