views:

14

answers:

1

My previous question asked for a way to keep a text view and slider in sync with bindings when modifying a CGRect's "x" value.

Following Peter Hosey's advice on using the controller's setter to propogate those changes to the CALayer, I came up with the following:

@interface WindowController : NSObject {
  CALayer *layer;
  float frameOriginX;
}
@end

@implementation WindowController
...
-(void)setFrameOriginX:(id)value {
  [layer setValue:[NSNumber numberWithFloat:[value floatValue]] 
       forKeyPath:@"frame.origin.x"];
  frameOriginX = [value floatValue];

}

-(float)frameOriginX {
 return [[layer valueForKeyPath:@"frame.origin.x"]floatValue];
}
@end

I used bindings to connect the text view and slider to "self.frameOriginX" and it's all working–both controls update each other. However, I was wondering what a cleaner way to do this is.

Thank You,

Charles

A: 

First off, why does setFrameOriginX: take an id and frameOriginX return a float? KVC will not like this. Plus, you should use CGFloat, not float.

Once you fix that, you're in luck. Today, Colin Barrett released SSGeometryKVC. With that, your setter becomes:

-(void)setFrameOriginX:(CGFloat)newX {
    frameOriginX = newX;
    [[layer mutableRectValueForKey:@"frame"].x = frameOriginX;
}

Note that neither this implementation nor your original implementation is thread-safe. This won't be a problem as long as it's only the controls that are calling it.

I used bindings to connect the text view and slider to "self.frameOriginX"…

Huh? If you bound them to the controller, you don't need self. here.

Peter Hosey
Thank you again Peter. Your help is very much appreciated.
Charles