动画期间的CALayer使用默认属性值,而不是当前实例的属性值

时间:2019-06-13 23:14:46

标签: swift uikit core-graphics core-animation calayer

我已经在xCode Playground中重新创建了我的问题,该示例对我遇到的错误进行了采样(显示往往更易于解释): https://gist.github.com/Wowserman/c1910523ad85cf34d3e08150b65c7074

我的问题是,我的CALayer类完美地绘制了它,在这个.gif文件中,您可以看到它第一次被渲染时的状态(底部带有阴影的绿色),并且很清楚,它应该如何渲染,但是一旦我开始为阴影高度设置动画,问题就出在这里。

我将shadowHeight的动画从12.0更改为0.0,然后将该动画反转,并且动画工作得很好,除了 color属性设法更改为默认值(黄色),而没有我的意图!

您可以在此gif文件中看到,该图层首先以绿色渲染(带有预期的阴影),然后是绿色,然后触摸视图并且该图层为阴影缩小设置了动画效果(但是{{1 }}在动画期间更改为默认值(黄色),一旦完成,它将返回到实例的正确color值。在整个动画中,动画应始终是color的值。

enter image description here

我检查了color属性是否从未更改,每次更改时都打印了一个 didSet 观察者,并且仅在初始化时才进行更改。

然后,我检查了 CALayer color方法,这就是我看到的draw(in ctx:)属性不同的地方。

我认为另一个可能的问题是color层是正确的,但是在切换它之后,我确定它不是问题。

我的问题总结

在动画过程中,图层的color属性谨慎更改为默认属性值,而不是初始化中设置的值,从而导致不必要的渲染。

2 个答案:

答案 0 :(得分:2)

我为需要的人找到了解决方案。激活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
}

如果您有好奇心,请在此处提供带有修复程序的更新Gist

https://gist.github.com/Wowserman/ca23d9596f2979effd9cc8fa9e73c893

答案 1 :(得分:1)

didSet的{​​{1}}观察者中-请勿呼叫color

您无意直接致电display()。如文档所述:

  

请勿直接调用此方法。图层会在适当的时候调用此方法以更新图层的内容。

相反,使用:

display

编辑:self.setNeedsDisplay() 函数也是如此。