2009-10-13 125 views
24

我有一个CABasicAnimation,动画的CALayer例如, bounds.origin。我希望能够观察随着时间的推移而变化的财产,但还没有真正找到一种100%有效的方法。观察CALayer动画属性更改

  1. 我试图在presentationLayerbounds.origin的keyPath使用KVO(键值观察)。系统抱怨说,在观察者被释放之前,对象被释放,导致我认为表示层只是暂时的。观察presentationLayer.bounds.origin作为键路径不起作用。

  2. 我试着在另一层上创建一个属性,通过在该层上声明@property并使其成为@dynamic。然而,当访问表示层时(例如,在动画结束时),这个新属性只会被改变,但在动画运行时似乎没有更新。

  3. 我在#2的属性,它确实在动画过程中触发更新使用needsDisplayForKey,但对于这些问题:

    • 如果CALayer具有非零帧它才会起作用。由于此图层可能是CAShapeLayer或子类,因此它可能具有零帧。
    • 它看起来像是为该图层触发setNeedsDisplay,但由于我实际上没有绘制该图层只监视属性更改,我不想让它重绘。
  4. 我试着安排一个NSTimer,并在定时器回调示例presentationLayer内。这也适用于这些问题:

    • 计时器可能会略微与动画更新不同步。
    • 由于有时候原始动画会被另一个动画取代,所以在动画运行时以及动画运行时很难启动计时器。

有什么建议吗?所有这些都将在iPhoneOS 3.0/3.1上。

回答

5

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

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

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

最好的问候。

+1

NSTimers被激发而不考虑实际图层何时被更新,它们总是稍微落后或在图层动画步骤的前面。我需要的是与图层动画同时通知*。最好的办法是使用CADisplayLink(仅限iPhone 3.1)或使用选项#3的人工图层来获得通知。最后,因为环境非常动态,我放弃了使用Core Animation来做到这一点 - 我现在使用NSTimer或CADisplayLink来执行自动滚动。 – 2009-10-14 21:57:58

+0

当我自动滚动时,有时在我要替换的图层中存在一个现有的自动滚动动画,有时最初的动画必须延迟1/2秒。因此,在实际的动画运行时很难*知道。 CAAnimation委托回调也不会即时发生,因此有可能任何依赖于它的代码都与动画图层中已经发生的内容不同步。 – 2009-10-14 22:04:52

+2

请参阅:http://developer.apple.com/mac/library/qa/qa2004/qa1385.html。 Apple文档说:“NSTimer是一个通用定时器,它不是一个与显示设备相连的定时器,定时器开始触发的时间间隔与垂直刷新时间无关,这意味着简单的方法以“60.0”Hz创建一个定时器注定会失败 - 定时器将相对于实际的刷新速率漂移,并且您将丢弃或加倍帧,这也意味着定时器将应用程序在任意点调入刷新...“ – 2009-10-14 22:08:54