I'm trying to understand how this method run(forKey:object:arguments:) is operating exactly in the following code from Apple's documentation:
let delegate = LayerDelegate()
lazy var sublayer: CALayer = {
let layer = CALayer()
layer.delegate = self.delegate
return layer
}()
func moveSublayer() {
guard let action = sublayer.action(forKey: "moveRight") else {
return
}
action.run(forKey: "transform", object: sublayer, arguments: nil) // this line
}
class LayerDelegate: NSObject, CALayerDelegate {
func action(for layer: CALayer, forKey event: String) -> CAAction? {
guard event == "moveRight" else {
return nil
}
let animation = CABasicAnimation()
animation.valueFunction = CAValueFunction(name: CAValueFunctionName.translateX)
animation.fromValue = 1
animation.toValue = 300
animation.duration = 2
return animation
}
}
I'm particularly confused about the forKey
parameter from action.run(forKey: "transform", object: sublayer, arguments: nil)
.
In the documentation, it's stated as:
The identifier of the action. The identifier may be a key or key path relative to anObject, an arbitrary external action, or one of the action identifiers defined in CALayer.
I understand that the animation list in the render tree is like a dictionary so you query the list with a key and you get a particular animation as a value, which is what happened in the example above. The sublayer queries the animation list with "moveRight":
guard let action = sublayer.action(forKey: "moveRight") else {
return
}
And then the action is returned with the following method:
func action(for layer: CALayer, forKey event: String) -> CAAction? {
guard event == "moveRight" else {
return nil
}
let animation = CABasicAnimation()
animation.valueFunction = CAValueFunction(name: kCAValueFunctionTranslateX)
animation.fromValue = 1
animation.toValue = 300
animation.duration = 2
return animation
}
But, what is this forKey: "transform" for? We've already queried the animation list with the "moveRight" key and got the value. Why do we need another key?
Also, what if I were to create a group animation combining transform and opacity or other non-transform property? What would I have to use instead of forKey: "transform"?
All CALayer properties are accessible by their string names via key-value coding. That fact is the basis of implicit layer animation and the entire CAAction mechanism.
Okay, well, there is no moveRight
property. "moveRight"
is just a name we made up. You have to ask yourself how we are going to move right.
In this example, we are going to do it by animating the layer's transform
, in particular using a translate transform with an X component that goes from 1 to 300 (as you see in the action(forLayer)
implementation). Hence we must use the "transform"
key, because we want to animate the transform
property.