我正在为iOS编写一条线,其中一条线作为CGPath中的一组点在CALayer上绘制。这条线从平坦的位置到具有不同y坐标但总是相同的x坐标的“模制”形状,有点像折线图动画。
为了使点插值更容易,我在我的CALayer子类中添加了一个自定义的CGFloat属性。我将这个属性称为'animator‘(更好的名称可能是progress、interpolator等)。我的想法是在这个属性上添加一个从0.0f到1.0f的简单CABasicAnimation,这样我就可以使用核心动画的计时功能和插值支持,同时仍然能够轻松地编写自定义动画。例如,如果一条线的点是从y= 100到y= 130,那么当动画制作人在0.0f时我在100,当它在1.0f时,我在点130,中间值给我我的临时点,我不断地用这些新的点重新绘制这条线,以获得我的动画。
现在动画效果很好,我已经禁用了图层动作,添加了needsDisplayForKey等,但我的问题是核心动画不准确。animator的最终值有时是.95、.96等,而不是1.0。这很好,因为浮点数有精度问题,但是当我的模型值更新时(在将动画添加到层之前设置为1.0f ),线应该会重新绘制,我应该会得到准确的视觉效果。
这是另一个问题出现的地方。有时,动画不会立即删除。大多数时候,它会被立即删除,我没有任何问题,但有时它会停留几秒钟,有时甚至几分钟。为了测试我的动画没有被移除的理论,我在我的层添加了一个简单的BOOL标志,当我们在表示层时,它返回YES,果然有时我看到我的最后一次drawInContext调用是在表示层,动画师的值是0.98967f或其他值,最后的drawInContext调用是动画师1.0f,表示层标志是NO。结果,我的视觉跳跃,除了明显的可怕的用户体验之外,并不准确。
我已经尽我所能地解释我的问题,如果有人想看代码,我很乐意提供我的测试项目。在这里,希望一些聪明人能看到这一点,并能帮助我。
编辑1:上传了整个Xcode项目(包括我讨厌的编辑,以显示我尝试过的所有内容) here。
编辑2:有类似问题的人在完成http://lucas.tiz.ma/blog/2012/04/18/core-animation-is-a-bit-garbage-collection-y/时手动删除动画
谢谢。
发布于 2012-10-11 15:45:24
tl;dr在动画中显式调用setNeedsDisplay dr:finished: delegate回调
根据Lucas Tizma的帖子(参见上面的编辑2),我尝试手动删除动画。我选择了一种比他的基于块的方法更简单的方法,将层设置为设置在层上的动画的代理。这样,动画开始和停止回调就会直接到达相关的层。显式删除animationDidStop:finished: call中的动画并不能解决这个问题。例如,有时(参见下面的日志,特别是时间戳),动画会停止,检查它是否被删除会显示它已经被删除,但是使用实际模型值进行精确绘制会发生很长一段时间。
// animationDidStop:finished: call back code
NSLog(@"layer animation stopped");
// check if any animations exist
NSLog(@"animation keys: %@", [self animationKeys]);
// remove animations and check
NSLog(@"removing animations");
[self removeAllAnimations];
NSLog(@"animation keys: %@", [self animationKeys]);
// log
2012-10-11 11:47:16.774 ASPathAnimationTest[3017:c07] on presentation layer 1
2012-10-11 11:47:16.774 ASPathAnimationTest[3017:c07] 335 animation draw update, animator is 0.982606
2012-10-11 11:47:16.775 ASPathAnimationTest[3017:c07] startPoint: {100, 90} - endPoint: {100, 100} - newPoint: {100, 99.8261}
<snip>
2012-10-11 11:47:16.791 ASPathAnimationTest[3017:c07] startPoint: {1000, 50} - endPoint: {1000, 100} - newPoint: {1000, 99.1303}
2012-10-11 11:47:16.792 ASPathAnimationTest[3017:c07] layer animation stopped
2012-10-11 11:47:16.792 ASPathAnimationTest[3017:c07] animation keys: (null)
2012-10-11 11:47:16.793 ASPathAnimationTest[3017:c07] removing animations
2012-10-11 11:47:16.793 ASPathAnimationTest[3017:c07] animation keys: (null)
2012-10-11 11:47:16.794 ASPathAnimationTest[3017:c07] layer animation stopped
2012-10-11 11:47:16.794 ASPathAnimationTest[3017:c07] animation keys: (null)
2012-10-11 11:47:16.794 ASPathAnimationTest[3017:c07] removing animations
2012-10-11 11:47:16.795 ASPathAnimationTest[3017:c07] animation keys: (null)
2012-10-11 11:47:16.795 ASPathAnimationTest[3017:c07] layer animation stopped
2012-10-11 11:47:16.819 ASPathAnimationTest[3017:c07] animation keys: (null)
2012-10-11 11:47:16.820 ASPathAnimationTest[3017:c07] removing animations
2012-10-11 11:47:16.820 ASPathAnimationTest[3017:c07] animation keys: (null)
2012-10-11 11:47:16.821 ASPathAnimationTest[3017:c07] layer animation stopped
2012-10-11 11:47:16.821 ASPathAnimationTest[3017:c07] animation keys: (null)
2012-10-11 11:47:16.821 ASPathAnimationTest[3017:c07] removing animations
2012-10-11 11:47:16.822 ASPathAnimationTest[3017:c07] animation keys: (null)
2012-10-11 11:47:16.822 ASPathAnimationTest[3017:c07] layer animation stopped
2012-10-11 11:47:16.822 ASPathAnimationTest[3017:c07] animation keys: (null)
2012-10-11 11:47:16.823 ASPathAnimationTest[3017:c07] removing animations
2012-10-11 11:47:16.823 ASPathAnimationTest[3017:c07] animation keys: (null)
2012-10-11 11:48:00.000 ASPathAnimationTest[3017:c07] on presentation layer 0
2012-10-11 11:48:00.000 ASPathAnimationTest[3017:c07] 336 animation draw update, animator is 1.000000
<snip, there are 5 lines so draw and point logs go here>
2012-10-11 11:48:00.021 ASPathAnimationTest[3017:c07] 340 animation draw update, animator is 1.000000
2012-10-11 11:48:00.023 ASPathAnimationTest[3017:c07] startPoint: {100, 90} - endPoint: {100, 100} - newPoint: {100, 100}
<snip>
2012-10-11 11:48:00.026 ASPathAnimationTest[3017:c07] startPoint: {1000, 50} - endPoint: {1000, 100} - newPoint: {1000, 100}
在查看日志并注意到动画确实被删除的事实后,只是使用实际准确的模型值重新绘制有时不会发生,直到几秒钟甚至几分钟后我更改了动画minutes :finished: delegate回调以显式调用图层上的setNeedsDisplay。对啰。
https://stackoverflow.com/questions/12798207
复制相似问题