Cocoa 来自CABASICANIATION的不可靠执行
我正在尝试在CALayer上实现自定义属性的动画。我已经将该属性设置为动态的,并且它基本上是有效的。在我的应用程序中,我可能有十几个或更多该层的实例,所有这些实例都应该同时设置动画。但是,有时在触发动画时,一些层不会执行动画。它们直接跳转到最终值 在尝试调试问题时,动画开始时,出现问题的层会在其模型层上使用动画特性的最终值进行重画。其余层仅使用动画特性的瞬时值在其表示层上重新绘制。通常是最后一层出现问题,但有时是随机层 这是如此零星,我真的不知道下一步该去哪里看 以下是触发动画的代码片段:Cocoa 来自CABASICANIATION的不可靠执行,cocoa,calayer,caanimation,Cocoa,Calayer,Caanimation,我正在尝试在CALayer上实现自定义属性的动画。我已经将该属性设置为动态的,并且它基本上是有效的。在我的应用程序中,我可能有十几个或更多该层的实例,所有这些实例都应该同时设置动画。但是,有时在触发动画时,一些层不会执行动画。它们直接跳转到最终值 在尝试调试问题时,动画开始时,出现问题的层会在其模型层上使用动画特性的最终值进行重画。其余层仅使用动画特性的瞬时值在其表示层上重新绘制。通常是最后一层出现问题,但有时是随机层 这是如此零星,我真的不知道下一步该去哪里看 以下是触发动画的代码片段: @d
@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];
}
@dynamicaspectmodefraction;
-(id)actionForKey:(NSString*)键
{
if([键isEqualToString:@“aspectModeFraction”])
{
CABasicAnimation*动画=[CABasicAnimation animationWithKeyPath:key];
animation.timingFunction=[CamediaTimingFunctionWithName:kCAMediaTimingFunctionEaseOut];
animation.fromValue=@([[self-presentationLayer]aspectModeFraction]);
animation.duration=2.0f;
animation.delegate=self;
返回动画;
}
返回[super-actionForKey:key];
}
+(BOOL)需要显示forkey:(NSString*)键{
if([@“fullRect”isEqualToString:key]){返回YES;}
if([@“localRect”isEqualToString:key]){返回YES;}
如果([@“screens”IsequalString:key]){返回YES;}
if([@“aspectModeFraction”isEqualToString:key]){返回YES;}
return[超级需要显示forkey:key];
}
看起来大部分零件都在您手中。自定义属性动画中有很多小部分,可能仍然有用,看起来你可能已经准备好了主要的东西
我首先怀疑电话号码。例如,我会确保您没有抑制动画,或者修改主线程上的任何UIKit片段
值得注意的是,官方可能不支持使用
@dynamic
复制图层属性的技巧。(这是其中一个“似乎有效”的东西,而不是我所知道的任何一个文档;当我和一些苹果工程师谈论它时,他们从来没有听说过这样做。)如果你只在10.9+上看到麻烦,您可以尝试将@dynamic
的使用替换为在initWithLayer:
中复制的标准属性。谢谢您的建议。我最终找到了问题所在。我优化了绘图代码,使其仅在该参数更改时进行一些计算。更新参数时,我将计算标记为脏,以便在下次绘制循环中重新计算。脏标志是通过参数上的自定义设置器设置的。当我切换到@dynamic(这似乎是CAAnimations所必需的?)时,自定义setter必须离开,因此我通过让对象本身执行KVO来更新脏标志。结果发现observeValueForKeyPath:。。。在动画中没有被调用。它得到了一个最终值的更新,但没有中间值
无论如何,放弃优化,每次都进行完整的计算就解决了这个问题。KVO上的动画值未按预期工作似乎是罪魁祸首 设置自定义属性的动画是官方的;苹果公司专门展示了如何做到这一点。事实上,整个动画系统是专门设计的,可以通过这种方式进行扩展。我知道您可以为自定义属性设置动画。事实上,我所说的@dynamic properties auto copy没有文档记录,可能也不受实际支持。如果查看链接的代码,它们将在
initWithLayer:
中实现复制,并使用@dynamic。(请参阅CustomAnimatableProperty/BulbLayer.m)您没有指出您有一个initWithLayer:
方法来处理此问题。您是如何要求动画的?根据我的经验,使用键值编码总是有效的。因此,如果你说的是,例如,myLayer.aspectModeFraction=which
,试着说[myLayer setValue:which forKey:@“aspectModeFraction”]
,看看这是否有区别。