开发者

Force redraw of custom cocoa control on property change

开发者 https://www.devze.com 2023-01-12 13:23 出处:网络
Lets say I have a custom control called FooBox. It is just a square on the screen. It has some properties like color, border, etc. When I change the properties, I want the FooBox to redraw itself to r

Lets say I have a custom control called FooBox. It is just a square on the screen. It has some properties like color, border, etc. When I change the properties, I want the FooBox to redraw itself to reflect its new properties. Is there a way to do that 开发者_运维问答without writing custom setters and putting [self setNeedsDisplay:YES] into all of them?


I am not certain if this is the right way to do it, but you could consider using NSKeyValueObserving and register the object as observer of itself, and do the redrawing in the -observeValueForKeyPath:ofObject:change:context: method.


EDIT: Peter is right in the comments, this solution only works if there is an observer registered for that property. I remember now that I had done this on a CALayer with @dynamic properties, in which case this works as you would like. In the general case though, this is not a good solution to your problem.

Assuming your class is KVC compliant for the properties which you want to trigger a redisplay, I would override the -didChangeValueForKey: method to call [self setNeedsDisplay] when the key matches one of your properties. I think this is slightly better than Peter's method of overriding -setValue:forKey: because it does not get in the way of the normal KVC machinery and doesn't require the boxing that he mentions.

- (void)didChangeValueForKey:(NSString*)key {
    if ([@"propertyOne" isEqualToString:Key] ||
        ....) {
        [self setNeedsDisplay];
    }
    [super didChangeValueForKey:key]; // <- Don't forget this
}


Two other ways:

  1. Have whatever is sending the view the accessor message send setNeedsDisplay:YES to it immediately after. Not always possible, and no less of a hassle.
  2. Override setValue:forKey: to add the setNeedsDisplay: message to it, and use that to set the view's properties. This will require boxing up any numeric or structure values, which is trading one hassle for another.

So, effectively, no.


I'm not aware of one. I'd write myself a few macros to do the trick if it bothered me enough.


If the properties are changed via an NSControl, you can always put

[theView setNeedsDisplay:YES]

in the action sent by the NSControl.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号