在自定义属性更改时重新绘制自定义CALayer子类

时间:2012-05-19 08:48:28

标签: cocoa core-animation quartz-graphics

我正在尝试构建一个绘制文本的特殊图层。此TWFlapLayer将属性字符串作为属性:

TWFlapLayer.h

@interface TWFlapLayer : CALayer
@property(nonatomic, strong) __attribute__((NSObject)) CFAttributedStringRef attrString;
@end

并在TWFlapLayer.m中合成:

@implementation TWFlapLayer

@synthesize attrString = _attrString;

/* overwrite method to redraw the layer if the string changed */

+ (BOOL)needsDisplayForKey:(NSString *)key
{
    if ([key isEqualToString:@"attrString"]){
        return YES;
    } else {
        return NO;
    }
}

- (void)drawInContext:(CGContextRef)ctx
{
    NSLog(@"%s: %@",__FUNCTION__,self.attrString);
    if (self.attrString == NULL) return;
    /* my custom drawing code */
}

我的意图是如果使用合成的setter方法更改了attrString属性,则使用我的自定义绘图方法自动重绘图层。但是,从放置在drawInContext:方法中的NSLog语句,我看到该层是而不是重绘。

通过在needsDisplayForKey方法中放置一个断点,我确保在询问attrString键时它返回YES。

我现在正在改变像这样的attrString

// self.frontString is a NSAttributedString* that is why I need the toll-free bridging
self.frontLayer.attrString = (__bridge CFAttributedStringRef) self.frontString;

//should not be necessary, but without it the drawInContext method is not called
[self.frontLayer setNeedsDisplay]; // <-- why is this still needed?

我在CALayer头文件中查找了needsDisplayForKey的类方法定义,但在我看来,这是我想要使用的方法,或者我在这里错过了重要的一点?

来自CALayer.h

/* Method for subclasses to override. Returning true for a given
 * property causes the layer's contents to be redrawn when the property
 * is changed (including when changed by an animation attached to the
 * layer). The default implementation returns NO. Subclasses should
 * call super for properties defined by the superclass. (For example,
 * do not try to return YES for properties implemented by CALayer,
 * doing will have undefined results.) */

+ (BOOL)needsDisplayForKey:(NSString *)key;

摘要

当自定义属性attrString被更改并标记为needsDisplayForKey:时,为什么我的图层不会重绘?

1 个答案:

答案 0 :(得分:14)

CALayer.h也说:

/* CALayer implements the standard NSKeyValueCoding protocol for all
 * Objective C properties defined by the class and its subclasses. It
 * dynamically implements missing accessor methods for properties
 * declared by subclasses.

显然needsDisplayForKey:机制依赖于CALayer动态实现的访问器方法。所以,改变这个:

@synthesize attrString = _attrString;

@dynamic attrString;
相关问题