Force cocoa user control change when property changes

Let's say I have a custom control called FooBox. It is just a square on the screen. It has some properties, such as color, border, etc. When I change properties, I want the FooBox to redraw itself to reflect its new properties. Is there a way to do this without writing user preferences and putting [self setNeedsDisplay: YES] in all of them?

+4
source share
5 answers

Two other ways:

  • Send what Accessor sends the message by sending it the message setNeedsDisplay:YES immediately after. Not always possible, and no less hassle.
  • Override setValue:forKey: to add the message setNeedsDisplay: to it, and use it to set view properties. This will require boxing any numerical or structural values ​​that trade one hassle for another.

So, effectively, no.

+1
source

I'm not sure if this is the right way to do this, but you can use NSKeyValueObserving and register the object as an observer of yourself and redraw in the -observeValueForKeyPath:ofObject:change:context: method.

+5
source

EDIT: Peter is right in the comments, this solution only works if an observer is registered for this property. I remember that I did it on CALayer with @dynamic properties, and in this case it works the way you would like. In general, this is not a good solution to your problem.

Assuming your class meets the KVC requirements for the properties you want to trigger a re-look, 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 the Peter overriding -setValue: forKey method: because it does not interfere with the normal KVC machine and does not require the box that it mentions.

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

I do not know about that. I will write myself some macros to do the trick, if that bothers me enough.

0
source

If properties are changed using NSControl, you can always set

 [theView setNeedsDisplay:YES] 

in action submitted by NSControl.

0
source

All Articles