CABasicAnimation 有个 fillMode 的属性,类型为 CAMediaTimingFillMode 。定义如下:
public struct CAMediaTimingFillMode : Hashable, Equatable, RawRepresentable {
public init(rawValue: String)
}
extension CAMediaTimingFillMode {
@available(iOS 2.0, *)
public static let forwards: CAMediaTimingFillMode
@available(iOS 2.0, *)
public static let backwards: CAMediaTimingFillMode
@available(iOS 2.0, *)
public static let both: CAMediaTimingFillMode
@available(iOS 2.0, *)
public static let removed: CAMediaTimingFillMode
}
fillMode:决定当前对象在非 active 时间段的行为。比如动画开始之前,动画结束之后。
另外,
removedOnCompletion代表动画执行完毕后就从图层上移除,图形会恢复到动画执行前的状态,默认为 true。如果想让图层保持显示动画执行后的状态,那就需要将removedOnCompletion设置为 false,并且将 fillMode 设置为 forwards。
CAMediaTimingFillMode 的各个 case
可以写一段程序来测试各个枚举值的对 layer 的影响。给一个 view 添加一个需要延迟 3 秒后执行的位移动画,查看 layer 的位移。
.forwards
let basicAnimation = CABasicAnimation()
basicAnimation.keyPath = "position.y";
basicAnimation.isRemovedOnCompletion = false
// beginTime : 动画的开始时间
// CACurrentMediaTime() : 图层的当前时间
// 让动画延迟3秒执行
basicAnimation.beginTime = CACurrentMediaTime()+3
basicAnimation.fillMode = .forwards
//动画的开始位置
basicAnimation.fromValue = 300;
//动画的结束位置
basicAnimation.toValue = 500;
//动画持续时间
basicAnimation.duration = 3;
animationView.layer.add(basicAnimation, forKey: nil)
结论:layer 添加了动画,在动画开始执行时,layer 迅速到动画的初始未知,然后开始执行动画。当 isRemovedOnCompletion 为 false 时停在动画结束的最后位置,为 true 是迅速返回到 layer 的本身位置。
.backwards
// 其他代码同 .forwards
basicAnimation.fillMode = .backwards
结论:在给 layer 添加了动画,layer 立即移动到动画的初始状态,3秒后动画开始执行。无论 isRemovedOnCompletion 的值,都迅速返回到 layer 的本身位置。
.both
// 其他代码同 .forwards
basicAnimation.fillMode = .both
结论:在给 layer 添加了动画,layer 立即移动到动画的初始状态,3秒后动画开始执行。当 isRemovedOnCompletion 为 false 时停在动画结束的最后位置,为 true 是迅速返回到 layer 的本身位置。
.both
// 其他代码同 .forwards
basicAnimation.fillMode = .removed
结论:在给 layer 添加了动画,layer 立即移动到动画的初始状态,3秒后动画开始执行。当 isRemovedOnCompletion 为 false 时停在动画结束的最后位置,为 true 是迅速返回到 layer 的本身位置。
总结
| case | 开始动画前 | 开始动画 | 动画结束 |
|---|---|---|---|
| forwards | 不动、保存原样 | 移动到开始动画的初始状态,开始执行动画 | 可以设置结束时的位置,当 isRemovedOnCompletion 为 false 时停在动画结束的最后位置,为 true 是迅速返回到layer 的本身位置 |
| backwards | 移动到开始动画的初始状态 | 开始执行动画 | 无法控制结束时的位置,无论 isRemovedOnCompletion 的值,都迅速返回到layer的本身位置 |
| both | 移动到开始动画的初始状态 | 开始执行动画 | 可以控制结束时的位置,当 isRemovedOnCompletion 为 false 时停在动画结束的最后位置,为 true 是迅速返回到layer 的本身位置 |
| removed | 不动、保存原样 | 移动到开始动画的初始状态,开始执行动画 | 无法控制结束时的位置,无论 isRemovedOnCompletion 的值,都迅速返回到layer的本身位置 |