Перерисовка пользовательского подкласса CALayer при изменении пользовательского свойства

Я пытаюсь создать специальный слой, который рисует текст. Этот 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 */
}

Мое намерение состояло в том, что слой автоматически перерисовывается с использованием моего пользовательского метода рисования, если свойство attrString было изменено с помощью синтезированного метода установки. Однако из оператора NSLog, помещенного в метод drawInContext:, я вижу, что слой не перерисовывается.

Поместив точку останова в метод needDisplayForKey, я убедился, что он возвращает YES при запросе ключа attrString.

Теперь я изменяю 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?

Я просмотрел определение метода класса для needDisplayForKey в заголовочном файле CALayer, но мне кажется, что это именно тот метод, который я хотел бы использовать, или я пропустил важный указать здесь?

из 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 изменено и помечено needDisplayForKey:?

9
задан GorillaPatch 19 May 2012 в 08:48
поделиться