背景#
以前の同僚が作成した画面にはアニメーションがあります。最初に移動するときは機能しますが、2 番目の画面に移動して戻るとアニメーションが消えてしまいます。アニメーションはCABasicAnimation
を使用してレイヤーに追加されています。
解決策#
コードを見ても問題はありません。最初には機能していたので、ページが消えるときに何か操作が行われたのかと思い、調べてみましたが、ページが消えるときには操作は行われていませんでした。
コードを再度確認すると、コードのアニメーション部分はdidMoveToWindow
メソッドで実装されています。以下は大まかなコードです:
didMoveToWindow
メソッドはページが消えるときと表示されるときの両方で呼び出されます。もしかして複数回追加されているために機能しなくなっているのかもしれません。一度だけ追加するように変更したところ、同じように機能しなくなりました。
override func didMoveToWindow() {
layer.addSublayer(gradientLayer)
let basicAnim = CABasicAnimation(keyPath: "animateLocation")
basicAnim.fromValue = [xxx]
basicAnim.toValue = [xxx]
basicAnim.duration = xxx
basicAnim.repeatCount = Float.infinity
gradientLayer.add(basicAnim, forKey: nil)
}
再度コードを確認すると、実装上の問題はないようですが、最後の行のkey
がnil
に設定されています。これが原因で問題が発生しているのかもしれません。
forKey: "basicAnim"
と設定し、効果を確認すると、問題が解決しました。ドキュメントを確認すると、確かにkey
はnil
に設定できますが、私自身も単純化のために単一のアニメーションの場合はkey
に値を設定せず、複数のアニメーションがある場合にのみkey
に値を設定するという習慣があります。やはり、出る杭は打たれるのですね...
最終的に機能するコードは以下のようになります:
override func didMoveToWindow() {
layer.addSublayer(gradientLayer)
let basicAnim = CABasicAnimation(keyPath: "animateLocation")
basicAnim.fromValue = [xxx]
basicAnim.toValue = [xxx]
basicAnim.duration = xxx
basicAnim.repeatCount = Float.infinity
gradientLayer.add(basicAnim, forKey: "basicAnim")
}