views:

355

answers:

1

I'm trying to bind a CGColorRef on one of my objects to the "shadowColor" property of a CALayer. Unfortunately, I haven't been able to figure this out - it's probably something really simple!

The CGColorRef is implemented as a property:

@property (readwrite) CGColorRef labelShadowColor;

My binding is straight forward too:

[aLayer bind:@"shadowColor" toObject:aScreen withKeyPath:@"labelShadowColor" options:nil];

Where I'm coming unstuck is valueForUndefinedKey: - how would I implement this for a CGColorRef? I'm currently getting the boilerplate:

2009-08-09 03:13:50.056 Hyperspaces[33161:a0f] An uncaught exception was raised
2009-08-09 03:13:50.060 Hyperspaces[33161:a0f] [<HSScreen 0x100533930> valueForUndefinedKey:]: this class is not key value coding-compliant for the key labelShadowColor.
2009-08-09 03:13:50.064 Hyperspaces[33161:a0f] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<HSScreen 0x100533930> valueForUndefinedKey:]: this class is not key value coding-compliant for the key labelShadowColor.'

I can work around this by putting an NSColor property on both ends and setting the CALayer's "shadowColor" manually whenever the color is changed, but that seems inelegant.

A: 

OK, so here's a tip that I missed (and how I solved it):

You can't synthesize CGColorRefs (@synthesize someProperty;) - you need to declare the property @dynamic and implement the getters/setters, like so:

@dynamic labelShadowColor;
- (CGColorRef)labelShadowColor {
    return labelShadowColor;
}

- (void)setLabelShadowColor:(CGColorRef)aShadowColor {
    if (CGColorEqualToColor(labelShadowColor,aShadowColor)) return;

    CGColorRelease(labelShadowColor);
    if (aShadowColor != NULL) {
     labelShadowColor = CGColorRetain(aShadowColor);
    }
}

Then you'll also need to define valueForUndefinedKey: in your class:

- (id)valueForUndefinedKey:(NSString *)key {
  if ([key isEqualToString:@"labelShadowColor"]) {
    return (id)self.labelShadowColor;
  }

  return [super valueForUndefinedKey:key];
}

Once these two things were done, my bindings sprang into action!

Tony Arnold