观察CALayer中的动画属性更改

时间:2009-10-13 00:56:27

标签: iphone objective-c macos core-animation calayer

我有CABasicAnimation动画CALayer的属性,例如bounds.origin。我希望能够观察到随时间变化的属性,但是还没有找到一种100%有效的方法。

  1. 我尝试在presentationLayer的{​​{1}}密钥路径上使用KVO(键值观察)。系统抱怨在释放观察者之前释放了对象,这使我认为表示层只是临时的。将bounds.origin视为关键路径不起作用。

  2. 我尝试在另一个图层上创建一个属性并为其设置动画,例如通过在该图层上声明presentationLayer.bounds.origin并将其设为@property。但是,只有在访问表示层时(例如在动画结束时)才会更改此新属性,但在动画运行时它似乎不会更新。

  3. 我在#2中的属性上使用@dynamic,它会在动画期间触发更新,但是对于这些问题:

    • 仅当needsDisplayForKey具有非零帧时才有效。由于该层可能是CAShapeLayer或子类,因此它可能具有零帧。
    • 看起来它会触发CALayer该图层,但由于我实际上并没有绘制该图层只监视属性更改,所以我不想让它重绘。
  4. 我尝试安排setNeedsDisplay,并在计时器回调示例中NSTimer。这也适用于这些问题:

    • 计时器可能与动画更新略有不同步。
    • 由于原始动画偶尔被另一个动画抢占,因此在动画运行时以及仅在动画运行时才能实际触发计时器。
  5. 有什么建议吗?所有这些都将在iPhoneOS 3.0 / 3.1上。

2 个答案:

答案 0 :(得分:5)

我认为你已经列出了所有可能性。事实上,我甚至没有意识到#2和#3,我写了the book on Core Animation。 ; - )

KVO不适用于这些属性。如果是的话会很好,但我相信这样做的原因与它需要的开销有关。该值将非常频繁地更新,并且必须回调任何观察者。

无论如何,我发现NSTimer是最可靠的方法,但现在我不确定你说的是什么。是什么让你认为计时器不同步?为什么难以让计时器仅在动画运行时触发?你不能只是在计时器回调中检查你想要的条件,如果不满足条件就不做任何事情吗?

最诚挚的问候。

答案 1 :(得分:5)

尝试使用CADisplayLink,它旨在与动画循环保持同步。更多信息:https://ashfurrow.com/blog/animating-views-with-cadisplaylink/