アニメーション結果を保持するためにCAAnimation.isRemovedOnCompletionをtrueにするべきではない。
参考: How to not use isRemovedOnCompletion for CAAnimation in iOS
fillColorやstrokeColorを変更すると暗黙的アニメーション(implicit animation)が発生するため、CATransaction.setDisableActions(_:)を使用して暗黙的アニメーションを無効化してfillColorやstrokeColorを変更する必要がある。
CATransaction+Extensions.swift
import QuartzCore
extension CATransaction {
/// 暗黙的アニメーション(implicit animations)が適用される変更をアニメーションなしで行うためのメソッド
///
/// https://stackoverflow.com/a/54784013
static func disableAnimations(_ completion: () -> Void) {
CATransaction.begin()
CATransaction.setDisableActions(true)
completion()
CATransaction.commit()
}
}
example.swift
func animate() {
let nextColor = UIColor.red.cgColor
let animation = CABasicAnimation(keyPath: "fillColor")
animation.fromValue = shapeLayer.fillColor
animation.toValue = nextColor
animation.duration = 2.0
layer.add(animation, forKey: animation.keyPath)
// アニメーションさせた後の状態を指定する
// 自前のアニメーションが無効化されないようにfillColorやstrokeColorの暗黙的アニメーションを無効化して色を変更する
CATransaction.disableAnimations {
self.layer.fillColor = nextColor
}
}