我试图在CALayer上实现自定义属性的动画。我已将该物业设置为动态,并且它主要起作用。在我的应用程序中,我可能有十几个或更多这个图层的实例,所有这些实例都应该同时生成动画。但是,有时当触发动画时,一些图层不会执行动画。他们简单地直接跳到最终值。
在尝试调试问题时,看起来当动画开始时,带有问题的图层会在其模型图层上重新绘制动画属性的最终值。其余图层仅使用动画属性的瞬态值在其表示层上重绘。它通常是有问题的最后一层,但有时它是随机层。
这是零星的,我不确定下一步该往下看。
这是触发动画的代码片段:
@dynamic aspectModeFraction;
- (id<CAAction>)actionForKey:(NSString *)key
{
if ([key isEqualToString:@"aspectModeFraction"])
{
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:key];
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
animation.fromValue = @([[self presentationLayer] aspectModeFraction]);
animation.duration = 2.0f;
animation.delegate = self;
return animation;
}
return [super actionForKey:key];
}
+ (BOOL)needsDisplayForKey:(NSString *)key {
if ([@"fullRect" isEqualToString:key]) { return YES; }
if ([@"localRect" isEqualToString:key]) { return YES; }
if ([@"screens" isEqualToString:key]) { return YES; }
if ([@"aspectModeFraction" isEqualToString:key]) { return YES; }
return [super needsDisplayForKey:key];
}
答案 0 :(得分:0)
看起来你有大部分的部分。自定义属性动画中有很多小部件,this talk可能仍然有用,看起来你可能已经掌握了重要的东西。
我首先怀疑调用代码。我确保你没有压制动画,或者修改主线程中的任何UIKit碎片。
值得注意的是,使用@dynamic
来复制图层属性的技巧可能无法正式支持。 (这似乎是“似乎有效”的事情之一,而不是出自我所知道的任何文件;当我与一些苹果工程师谈过这件事时,他们从来没有听说过那样做。)如果你'只有10.9+才能看到问题,您可以尝试将@dynamic
的使用替换为您在initWithLayer:
中复制的标准属性。
答案 1 :(得分:0)
感谢您的建议。我最终追查了这个问题。我已经优化了绘图代码,只在这个参数改变时做了一些计算。当参数更新时,我将计算标记为脏,因此在下一个绘制循环期间将重新计算它们。脏标志是通过参数上的自定义设置器设置的。当我切换到@dynamic(这似乎是CAAnimations需要?)时,自定义setter必须消失,所以我通过让对象自己做KVO来更新脏标志。事实证明,observeValueForKeyPath:...在动画期间没有被调用。它有一个最终值的更新,但没有中间体。
无论如何,每次解决问题时都放弃优化并进行完整计算。 KVO对动画价值没有按预期工作似乎是罪魁祸首。