29

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

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

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

  3. needsDisplayForKey在#2 中使用了属性,它确实会在动画期间触发更新,但是对于这些问题:

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

    • 计时器可能与动画更新稍微不同步。
    • 由于有时原始动画会被另一个动画抢占,因此很难真正让计时器在动画运行时触发,并且仅在动画运行时触发。

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

4

3 回答 3

6

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

于 2015-12-16T22:22:21.503 回答
5

我想你已经列出了所有的可能性。事实上,我什至不知道#2 和#3,我写了关于 Core Animation 的书。;-)

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

无论如何,我发现 NSTimer 是最可靠的方法,但现在我不确定你所说的。是什么让您认为计时器不同步?为什么只有在动画运行时才触发计时器很困难?难道你不能在计时器回调中检查你想要的条件,然后如果条件不满足就什么都不做吗?

最好的祝福。

于 2009-10-13T03:37:59.067 回答
0

对我来说最好的解决方案是同时使用:CABasicAnimation 和 CADisplayLink。您可以开始观察开始动画的变化并在其结束时完成。您也可以计算每个步骤,但要注意时序逻辑。当您使用线性时序时,它将起作用。或者您必须基于 CADisplayLink 在您的类上准备类似的逻辑(转换与时间变化保持一致)。

于 2021-10-17T22:20:57.253 回答