2012-05-19 13 views
9

Estoy intentando crear una capa especial que dibuje texto. Este TWFlapLayer tiene una cadena con atributos como una propiedad:Redibujar la subclase de CALayer personalizada en el cambio de propiedad personalizada

TWFlapLayer.h:

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

y obtiene sintetizados en 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 */ 
} 

Mi intención era que la capa se vuelve a dibujar de forma automática usando mi método de dibujo personalizado si la propiedad attrString se modificó utilizando el método setter sintetizado. Sin embargo, desde la declaración NSLog colocada en el método drawInContext: veo que la capa es no redibujada.

Al colocar un punto de interrupción en el método needsDisplayForKey, me aseguré de que devolviese SÍ cuando me pidieron la clave attrString.

ahora estoy cambiando el attrString como esto

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

busqué la definición del método de clase para needsDisplayForKey en el archivo de cabecera CALayer, pero me parece que este es el método me gustaría usar o ¿Me estoy perdiendo un punto importante aquí?

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

Resumen

¿Por qué mi capa de no volver a dibujar cuando el attrString propiedad personalizada se cambia y marcado por needsDisplayForKey:?

Respuesta

14

CALayer.h también dice:

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

Al parecer, el mecanismo de needsDisplayForKey: se basa en métodos de acceso implementados de forma dinámica de CALayer. Por lo tanto, cambiar esta situación:

@synthesize attrString = _attrString; 

a

@dynamic attrString; 
+0

Eso fue genial! Eso hizo el truco. El 'CALayer.h' realmente es un archivo enorme, un poco vergonzoso que me haya perdido este punto. – GorillaPatch

+0

@ kurt-revis Tuve un problema similar y @dynamic funciona bien, gracias. Pero podría explicar por qué la representación inicial no me sucede, aunque configuré el valor inicial en el método '- (id) init'. needsDisplayForKey simplemente no se activa en 'init'. – Andy

+0

¿Has intentado llamar a '-setNeedsDisplay' en' init'? – ipmcc

Cuestiones relacionadas