はじめに
CoreAnimationを使って少し凝ったアニメーション等を実装する時に、毎回おまじないのようにfillMode
を設定していたのですが、それについて少し調べたので書いていきたいと思います
fillModeとは
アニメーションの終了時の動作を決めるためのプロパティだと理解しています
fillModeの種類と役割
- removed:
アニメーションが終了したら削除する。デフォルトでremovedが設定されています - forwards:
アニメーションが終了時は最後の状態を保持する - backwards:
アニメーションが終了時は最初の状態で固定する - both:
forwardsとbothの両方を適用したもの
実際に動きを見てみる
ベースとなるコード
backgroundColor
をgreen
にしただけのUIView
があります。
let animatedView = UIView(frame: CGRect(origin: .zero, size: CGSize(width: 100, height: 100)))
animatedView.backgroundColor = .green
animatedView
をCoreAnimationを使って、origin.x
を200に、backgroundColor
をblue
にアニメーションさせます
let translateAnimation = CABasicAnimation(keyPath: "transform.translation.x")
translateAnimation.beginTime = CACurrentMediaTime() + 0.5
translateAnimation.duration = 1.0
translateAnimation.fromValue = CATransform3DIdentity
translateAnimation.toValue = 200
translateAnimation.isRemovedOnCompletion = false
let backgroundAnimation = CABasicAnimation(keyPath: #keyPath(CALayer.backgroundColor))
backgroundAnimation.beginTime = CACurrentMediaTime() + 0.5
backgroundAnimation.duration = 1.0
backgroundAnimation.fromValue = UIColor.green.cgColor
backgroundAnimation.toValue = UIColor.blue.cgColor
backgroundAnimation.isRemovedOnCompletion = false
animatedView.layer.add(backgroundAnimation, forKey: nil)
animatedView.layer.add(translateAnimation, forKey: nil)
※アニメーションがわかりやすくなるようにisRemovedOnCompletion
をfalse
にしています
これらにfillMode
を設定して挙動を違いを見ていきます。
.removed
の時
fillMode
のデフォルト値が.removed
なので、先程のコードのままでも同じ挙動になります。
...
+translateAnimation.fillMode = .removed
...
+backgroundAnimation.fillMode = .removed
...
アニメーションが終わった時、アニメーションが削除されて初期状態に戻っているのがわかります。
.forwards
の時
両方のfillMode
を.forwards
に設定します。
...
+translateAnimation.fillMode = .forwards
...
+backgroundAnimation.fillMode = .forwards
...
アニメーションが終わった時、最後の状態を保持し続けているのがわかります。
.backwards
の時
両方の.fillMode
をbackwards
に設定します。
...
+translateAnimation.fillMode = .backwards
...
+backgroundAnimation.fillMode = .backwards
...
.removed
の時と同じ挙動になってしまいました。わかりづらいので、translateAnimation
のfillMode
だけ.forwards
にして見たいと思います。
...
-translateAnimation.fillMode = .backwards
+translateAnimation.fillMode = .forward
...
+backgroundAnimation.fillMode = .backwards
...
最後のbackground
の状態がgreen
になっている通り、アニメーションが終わった時、最初の状態を保持しているのがわかります。
.both
の時
両方のfillMode
に.both
を設定します。
...
+translateAnimation.fillMode = .both
...
+backgroundAnimation.fillMode = .both
...
見かけでは .forwards
と一緒ですが、連続で何回もアニメーションすると違いがわかります。
.both
を連続でアニメーションさせた時
.forward
を連続でアニメーションさせた時
.both
だといい感じになっていますね。
最後に
基本的には、isRemovedOnCompletion = false
と.fillMode = .forwards
の組み合わせで使うことがほとんどだと思いますが、他にもこんなプロパティがあるよ、という紹介でした。