I've recreated my problem in a xCode Playground that samples the bug I'm running into (showing tends to be better at explaining): https://gist.github.com/Wowserman/c1910523ad85cf34d3e08150b65c7074
My problem is this, my CALayer class renders it's drawing perfectly, in this .gif you can see what it is when it is first rendered (Green with a shadow at the bottom) and to be clear that renders how it should, but as soon as I start animating the shadow height is where the problem is.
I animated the shadowHeight
from 12.0 to 0.0 and reverse that animation, and well the animation works except the color
property manages to change to the default value (Yellow) without my intent!
You can see in this gif, the layer is first rendered in, Green with the shadow (which is intended), then when the view is touched and the layer animates the shrink of the shadow (intended) but the color
changes to the default value (Yellow) during the animation and once it is complete it goes back to the instance's proper color
value. The animation should be the color
's value at all times throughout the animation.
I checked that the color
property is never changed, I have a didSet observer printing every time it is changed, and it is only changed during initialization which is how it should be.
I then checked in the draw(in ctx:)
method of CALayer and that's where I saw the color
property was different.
Another possible problem I thought could be that the layer drawsAsynchronously
is true, but after toggling it I identified it as not the problem.
My Problem Summed Up:
The layer's color property is discreetly changing to the default property value during the animation instead of the value set in initialization causing unwanted rendering.
I figured out the solution for anyone in need. When a CALayer is animated, the CALayer isn't mutated, rather it is duplicated by using CALayer's init(layer:)
.
I was reading the documentation on this initializer (enter link description here) and found that inside the override you are suppose to copy layer
's custom properties to the new CALayer subclass.
public override init(layer: Any) {
super.init(layer: layer)
self.common()
guard let overlay = layer as? OverlayLayer else {
return
}
self.color = overlay.color
}
Here's an update Gist with the fix if you're curious
https://gist.github.com/Wowserman/ca23d9596f2979effd9cc8fa9e73c893