I am trying to use the #keyPath syntax in order to get a CALayer property to animate it like this:
let myAnimation = CABasicAnimation.init(keyPath: #keyPath(CALayer.position.x))
and I get the following error:
Type 'CGPoint' has no member 'x'
What am I missing?
The #keyPath
directive expects an Objective-C property sequence as
argument. CALayer
inherits from NSObject
, but its position
property is struct CGPoint
, which is not a class at all, and cannot
used with Key-Value coding.
However, CALayer
has a special implementation of value(forKeyPath:)
which handles the entire key path, instead of evaluating the first key and passing down the remaining key path, compare KVC strange behavior.
So Key-Value Coding can be used with "position.x", but the compiler does not know about this special treatment. As an example, this all compiles and runs:
let layer = CALayer()
layer.position = CGPoint(x: 4, y: 5)
print(layer.value(forKeyPath: "position")) // Optional(NSPoint: {4, 5}
print(layer.value(forKeyPath: "position.x")) // Optional(4)
print(layer.value(forKeyPath: #keyPath(CALayer.position))) // Optional(NSPoint: {4, 5})
but this does not compile:
print(layer.value(forKeyPath: #keyPath(CALayer.position.x)))
// error: Type 'CGPoint' has no member 'x'
That is the reason why
let myAnimation = CABasicAnimation(keyPath: #keyPath(CALayer.position.x))
does not compile, but this does (as Reinier Melian suggested):
let myAnimation = CABasicAnimation(keyPath: "position.x")
position
is a property in object of type CALayer
and you want to access it from base class , second keyPath takes a property to animate in the layer and CALayer.position.x
is not a property inside CALayer object that you want to animate , so it must be position.x
that you can't write directly without string "" as you will have error saying can't find position in the class you want to declare it in , so proper way would be like this
let myLayer = CALayer.init()
myLayer.frame = CGRect(x: 0, y: 0, width: 20, height: 20)
let anim = CABasicAnimation.init(keyPath: "position.x")
anim.fromValue = 20
anim.toValue = 100
anim.duration = 1
myLayer.add(myAnimation, forKey: "position.x")
self.view.layer.addSublayer(myLayer)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With