2012-05-19 119 views
9

我正在嘗試構建一個繪製文本的特殊圖層。這TWFlapLayer有一個屬性串作爲一個屬性:自定義屬性更改時重繪自定義CALayer子類

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。

我現在改變這樣

// 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的attrString,但在我看來,這是我想使用的方法或我錯過了重要的一點嗎?

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:爲什麼不重繪我的層?

回答

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; 
+0

這是偉大的!那就是訣竅。 「CALayer.h」真的是一個巨大的文件,有點尷尬,我錯過了這一點。 – GorillaPatch

+0

@ kurt-revis我有類似的問題和@dynamic工作正常,謝謝。但是,你能否解釋爲什麼初始渲染不會發生在我身上,即使我在' - (id)init'方法中設置了初始值。 needsDisplayForKey不會在'init'中觸發。 – Andy

+0

您是否嘗試過在'init'中調用'-setNeedsDisplay'? – ipmcc