Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cocoa 在自定义属性更改时重新绘制自定义CALayer子类_Cocoa_Core Animation_Quartz Graphics - Fatal编程技术网

Cocoa 在自定义属性更改时重新绘制自定义CALayer子类

Cocoa 在自定义属性更改时重新绘制自定义CALayer子类,cocoa,core-animation,quartz-graphics,Cocoa,Core Animation,Quartz Graphics,我试图建立一个特殊的层,绘制文本。此TWFlapLayer具有属性字符串作为属性: TWFlapLayer.h: @interface TWFlapLayer : CALayer @property(nonatomic, strong) __attribute__((NSObject)) CFAttributedStringRef attrString; @end /* Method for subclasses to override. Returning true for a given

我试图建立一个特殊的层,绘制文本。此
TWFlapLayer
具有属性字符串作为属性:

TWFlapLayer.h

@interface TWFlapLayer : CALayer
@property(nonatomic, strong) __attribute__((NSObject)) CFAttributedStringRef attrString;
@end
/* 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;
并在
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?
摘要


当自定义属性attrString被更改并由
needsDisplayForKey:
标记时,为什么我的图层没有重新绘制?

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.
显然,
需要displayforkey:
机制依赖于CALayer动态实现的访问器方法。因此,改变这一点:

@synthesize attrString = _attrString;


太棒了!这就成功了。
CALayer.h
确实是一个很大的文件,我错过了这一点有点尴尬。@kurt revis我也有类似的问题,@dynamic工作正常,谢谢。但是你能解释一下为什么初始渲染不会发生在我身上,即使我在
-(id)init
方法中设置了初始值。needsDisplayForKey不会在
init
中触发。
@dynamic attrString;