のサブクラスでアニメート可能なカスタム プロパティを作成しようとしていますCALayer
。Web でこれに関する参考文献をいくつか見つけましたが、まだ Objective C にあるものもあります。これは、これまでに学んだことを示す Swift の実験的なレイヤーです。2 つの新しいCGColor
プロパティを定義tileColor
しますtintColor
。は、タイリング、Formica ブーメラン パターンなどtileColor
から通常作成するある種のパターンです。は私の新しいアニメート可能なプロパティです。赤や緑のような無地の色で、パターンと組み合わされて着色されているように見えます。UIImage
tintColor
class TintedTile: CALayer {
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override init () {
self.tileColor = UIColor.clear.cgColor
self.tintColor = UIColor.clear.cgColor
super.init (); self.borderColor = nil
}
override init(layer model: Any) {
let model = model as! TintedTile
self.tileColor = model.tileColor
self.tintColor = model.tintColor
super.init (layer: model)
print ("TintedTile: presentation layer Added")
}
deinit {
print ("TintedTile: presentation layer Removed")
}
class override func needsDisplay(forKey key: String) -> Bool {
super.needsDisplay(forKey: key) || key == #keyPath(TintedTile.tintColor)
}
var tileColor: CGColor {
didSet {
self.setNeedsDisplay()
}
}
@objc var tintColor: CGColor
override func draw(in ctx: CGContext) {
ctx.setBlendMode(.multiply)
ctx.setFillColor(tileColor); ctx.fill(bounds)
ctx.setFillColor(tintColor); ctx.fill(bounds)
}
}
tintColor
私はとしてタグ付けされて@objc
おり、クラス関数をオーバーライドしてneedsDisplay(forKey:)
、アニメーション化可能であると識別されるようにしました。そして、暗黙的なアニメーションと明示的なアニメーションの両方で、すべてが完全に機能しているように見えます。tintColor
新しいトリガーを暗黙的なアニメーションに設定するには、オーバーライドする必要があることを理解しているため、これは奇妙ですaction(forKey:)
。
override func action(forKey event: String) -> CAAction? {
guard event == #keyPath(TintedTile.tintColor) else { return super.action(forKey: event) }
print ("TintedTile action(forKey:)")
let anim = CABasicAnimation (keyPath: event)
anim.fromValue = self.tintColor; return anim
}
私はこれを少し正しくやっているとは思いませんが、問題ではないようです。関数が呼び出されることはないようです。完全にコメントアウトしても、暗黙のアニメーションは引き続き発生します。確認するためにレイヤーの速度を 1/10 に下げてみましたが、瞬間的な変化ではなく、時間の経過とともに確実に色が変化します。このオーバーライドは必要ですか?
しかし、私の本当の懸念は、露骨なアニメーションです。プレゼンテーション レイヤーのライフ サイクルを表示できるかどうか疑問に思ったので、print
ステートメントを入れinit(layer:)
てdeinit
. プレゼンテーション レイヤーは、オブジェクトがレイヤーに初めてCAAnimation
追加されたときに作成され、最後のアニメーションが削除されるか、完了してそれ自体が削除されるまで存続すると考えていました。実際に起こっているように見えるのは、アニメーションのフレームごとに個別のレイヤーが作成および削除されていることです。つまり、CABasicAnimation
を 1 秒間実行するように設定した場合、約 60 のレイヤーの作成と破棄が見られ、他のアニメーションの長さでは比例した数のレイヤーが表示されます。
これは実際に起こっていることですか?カラー シフト効果は完璧に見えますが、フレームごとにプレゼンテーション レイヤーが解放されている場合、アニメーションの状態はどこで維持されているのでしょうか? そして、これは不必要な計算負荷を作成および破壊していませんか? 私は自分が何か間違ったことをしている、またはすべきことをしていないと感じています。何かご意見は?