gpt4 book ai didi

objective-c - CALAyer 子类中的不可动画属性

转载 作者:行者123 更新时间:2023-12-03 07:45:22 25 4
gpt4 key购买 nike

我已经定义了 CALayer 的子类,其具有可动画属性,如所讨论的 here 。我现在想向该层添加另一个(不可设置动画的)属性以支持其内部簿记。

我在drawInContext:中设置了新属性的值,但我发现在下次调用时它总是重置为0。是因为 Core Animation 假设该属性也用于动画,并且它在常量 0 处“动画”其值,而缺乏进一步的说明吗?无论如何,如何将真正不可动画的属性添加到 CALayer 的子类中?

我找到了一个初步的解决方法,即使用全局 CGFloat _property 而不是 @property(分配)CGFloat 属性,但更喜欢使用普通属性语法。

更新1

这就是我尝试在 MyLayer.m 中定义属性的方式:

@interface MyLayer()

@property (assign) CGFloat property;

@end

这就是我在 drawInContext: 末尾为其赋值的方式:

self.property = nonZero;

该属性例如在 drawInContext: 的开头读取,如下所示:

NSLog(@"property=%f", self.property);

更新2

也许这就是导致问题的原因(从 this 示例继承的代码)?

- (id)actionForKey:(NSString *) aKey {
if ([aKey isEqualToString:@"someAnimatableProperty"]) {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:aKey];
animation.fromValue = [self.presentationLayer valueForKey:aKey];
return animation;
}
return [super actionForKey:aKey]; // also applies to my "property"
}

最佳答案

要在动画期间从绘图方法中访问标准属性,您需要进行一些修改。

实现初始化器

当 CoreAnimation 执行动画时,它会创建图层的阴影副本,并且每个副本将在不同的帧中渲染。为了创建这样的副本,它调用 -initWithLayer: 。来自 Apple's documentation :

If you are implementing a custom layer subclass, you can override this method and use it to copy the values of instance variables into the new object. Subclasses should always invoke the superclass implementation.

因此,您需要实现-initWithLayer:并使用它手动复制新实例上的属性值,如下所示:

- (id)initWithLayer:(id)layer
{
if ((self = [super initWithLayer:layer])) {
// Check if it's the right class before casting
if ([layer isKindOfClass:[MyCustomLayer class]]) {
// Copy the value of "myProperty" over from the other layer
self.myProperty = ((MyCustomLayer *)layer).myProperty;
}
}
return self;
}

通过模型层访问属性

无论如何,复制发生在动画开始之前:您可以通过添加 NSLog 来看到这一点调用-initWithLayer: 。所以据 CoreAnimation 所知,你的属性将永远为零。此外,如果您尝试设置 self.myProperty,它创建的副本是只读的。从内部-drawInContext: ,当在演示文稿副本之一上调用该方法时,您会得到一个异常:

*** Terminating app due to uncaught exception 'CALayerReadOnly', reason:  
'attempting to modify read-only layer <MyLayer: 0x8e94010>' ***

而不是设置 self.myProperty ,你应该写

self.modelLayer.myProperty = 42.0f

modelLayer相反,会引用原始的 MyCustomLayer实例,并且所有演示副本共享相同的模型。请注意,您在读取变量时也必须执行此操作,而不仅仅是在设置变量时。为了完整起见,还应该提及属性 presentationLayer ,而是返回当前显示的图层(副本)。

关于objective-c - CALAyer 子类中的不可动画属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24597797/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com