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