动画期间的 CALayer 使用默认 属性 值而不是当前实例的 属性 值
CALayer during animation is using default property value instead of what should be the current instance's property value
我在 xCode Playground 中重新创建了我的问题,该 Playground 对我 运行 遇到的错误进行了采样(展示往往更善于解释):
https://gist.github.com/Wowserman/c1910523ad85cf34d3e08150b65c7074
我的问题是,我的 CALayer class 完美地渲染了它的绘图,在这个 .gif 中你可以看到它第一次渲染时的样子(底部有阴影的绿色)并且很清楚渲染它应该如何,但是一旦我开始动画阴影高度就是问题所在。
我将 shadowHeight
从 12.0 设置为 0.0 并反转该动画,除了 color
属性 管理外,动画效果很好在我无意的情况下更改为默认值(黄色)!
你可以在这张 gif 中看到,图层首先呈现为绿色和阴影(这是有意的),然后当视图被触摸时,图层会动画化阴影的收缩(有意的)但是 color
在动画期间更改为默认值(黄色),一旦完成,它将返回到实例的正确 color
值。在整个动画过程中,动画应该始终是 color
的值。
我检查过 color
属性 永远不会改变,我有一个 didSet 观察者每次改变时打印,它只是改变了在初始化过程中应该是这样。
然后我检查了 CALayer 的 draw(in ctx:)
方法,那是我看到 color
属性 不同的地方。
我认为另一个可能的问题可能是图层 drawsAsynchronously
是正确的,但在切换它之后我发现它不是问题所在。
我的问题总结:
层的颜色 属性 在动画期间悄悄更改为默认 属性 值,而不是初始化时设置的值,导致不需要的渲染。
在 color
上的 didSet
观察者中 - 不要调用 display()
您不应该直接调用 display
。正如文档所述:
Do not call this method directly. The layer calls this method at appropriate times to update the layer’s content.
改为使用:
self.setNeedsDisplay()
编辑:您的 common()
函数也是如此。
我为有需要的人找到了解决方案。为 CALayer 设置动画时,CALayer 不会发生变化,而是通过使用 CALayer 的 init(layer:)
.
进行复制
我正在阅读有关此初始化程序 (enter link description here) 的文档,发现在重写内您应该将 layer
的自定义属性复制到新的 CALayer 子类。
public override init(layer: Any) {
super.init(layer: layer)
self.common()
guard let overlay = layer as? OverlayLayer else {
return
}
self.color = overlay.color
}
如果你好奇的话,这里有一个包含修复的更新要点
https://gist.github.com/Wowserman/ca23d9596f2979effd9cc8fa9e73c893
我在 xCode Playground 中重新创建了我的问题,该 Playground 对我 运行 遇到的错误进行了采样(展示往往更善于解释): https://gist.github.com/Wowserman/c1910523ad85cf34d3e08150b65c7074
我的问题是,我的 CALayer class 完美地渲染了它的绘图,在这个 .gif 中你可以看到它第一次渲染时的样子(底部有阴影的绿色)并且很清楚渲染它应该如何,但是一旦我开始动画阴影高度就是问题所在。
我将 shadowHeight
从 12.0 设置为 0.0 并反转该动画,除了 color
属性 管理外,动画效果很好在我无意的情况下更改为默认值(黄色)!
你可以在这张 gif 中看到,图层首先呈现为绿色和阴影(这是有意的),然后当视图被触摸时,图层会动画化阴影的收缩(有意的)但是 color
在动画期间更改为默认值(黄色),一旦完成,它将返回到实例的正确 color
值。在整个动画过程中,动画应该始终是 color
的值。
我检查过 color
属性 永远不会改变,我有一个 didSet 观察者每次改变时打印,它只是改变了在初始化过程中应该是这样。
然后我检查了 CALayer 的 draw(in ctx:)
方法,那是我看到 color
属性 不同的地方。
我认为另一个可能的问题可能是图层 drawsAsynchronously
是正确的,但在切换它之后我发现它不是问题所在。
我的问题总结:
层的颜色 属性 在动画期间悄悄更改为默认 属性 值,而不是初始化时设置的值,导致不需要的渲染。
在 color
上的 didSet
观察者中 - 不要调用 display()
您不应该直接调用 display
。正如文档所述:
Do not call this method directly. The layer calls this method at appropriate times to update the layer’s content.
改为使用:
self.setNeedsDisplay()
编辑:您的 common()
函数也是如此。
我为有需要的人找到了解决方案。为 CALayer 设置动画时,CALayer 不会发生变化,而是通过使用 CALayer 的 init(layer:)
.
我正在阅读有关此初始化程序 (enter link description here) 的文档,发现在重写内您应该将 layer
的自定义属性复制到新的 CALayer 子类。
public override init(layer: Any) {
super.init(layer: layer)
self.common()
guard let overlay = layer as? OverlayLayer else {
return
}
self.color = overlay.color
}
如果你好奇的话,这里有一个包含修复的更新要点
https://gist.github.com/Wowserman/ca23d9596f2979effd9cc8fa9e73c893