2012-05-19 10 views
9

Próbuję utworzyć specjalną warstwę, która rysuje tekst. Ten TWFlapLayer ma nadany ciąg jako właściwość:Przerysowywanie niestandardowej podklasy programu CALayer przy zmianie właściwości niestandardowej

TWFlapLayer.h:

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

i dostaje syntetyzowany w 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 */ 
} 

Moją intencją było to, że warstwa jest automatycznie odnawiany za pomocą mojego niestandardową metodę rysowania jeśli właściwość attrString została zmieniona za pomocą metody syntetyzowanej setera. Jednak z instrukcji NSLog umieszczonej w metodzie drawInContext: widzę, że warstwa jest , a nie przerysowana.

Umieszczając punkt przerwania w metodzie needsDisplayForKey, upewniłem się, że zwraca TAK, gdy zostanie zapytany o klucz attrString.

Jestem teraz zmieniając attrString jak ten

// 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? 

Spojrzałam definicję metody klasy dla needsDisplayForKey w pliku nagłówkowym CALayer, ale wydaje mi się, że jest to metoda chciałbym używać ani czy brakuje tu ważnej kwestii?

z 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; 

Podsumowanie

Dlaczego nie jest mój warstwa przerysowywania gdy attrString zwyczaj właściwość zostanie zmieniona i naznaczone needsDisplayForKey:?

Odpowiedz

14

CALayer.h mówi:

/* 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. 

Najwyraźniej mechanizm needsDisplayForKey: opiera się na dynamicznie wdrożonych metod dostępowych CALayer użytkownika. Tak, to zmienić:

@synthesize attrString = _attrString; 

do

@dynamic attrString; 
+0

To było świetne! To wystarczyło. "CALayer.h" to naprawdę ogromny plik, trochę zawstydzający, że tęskniłem za tym punktem. – GorillaPatch

+0

@ kurt-revis Miałem podobny problem i @dynamic działa dobrze, dzięki. Ale czy mógłbyś wyjaśnić, dlaczego początkowe renderowanie nie dzieje się dla mnie, mimo że ustawiłem wartość początkową w metodzie '- (id) init'. needsDisplayForKey po prostu nie uruchamia się w 'init'. – Andy

+0

Czy próbowałeś wywoływać '-setNeedsDisplay' w' init'? – ipmcc

Powiązane problemy