NSValueTransformer

Hello Everybody,

I just wanted to know: there is a “Value Transformer” field in IB bindings. I’ve read this value transformer is a class which will be invoked to return a result.

Say I want an image to be set on a “Green” picture if a value “test” in the arrangedObjects of a controller is equal to a value “target” in the same array. To do it with bindings, do I have to subclass NSValueTransformer?

So to set the “hidden” flag of a control: it’s easy to do if the condition is boolean (control hidden if this property <> 0, using NSNegateBoolean and so on). But what if I want the control to be hidden if the property is, say, “3” or “less than 2”?

I know how to do it by code, it’s easy, it does not require more than an IF test. But with bindings?

Maybe I’m a bit compulsive with bindings but I love the concept. :stuck_out_tongue:

Regards,

Hi,

actually the proper way is keyPathsForValuesAffectingValueForKey: of NSObject which uses key value observing.
Short ObjC explanation, but it should work also in ASOC.

There is a generic +keyPathsForValuesAffecting method. represents the key to be entered in the bindings key path field. The method must return a set of (literal string) keypaths.

The respective variables must be key-value-observing compliant (defined as properties)

For example you want to hide something depending on the number of items in an array,
the +keyPathsForValuesAffecting method is


+ (NSSet *)keyPathsForValuesAffectingHideSomething
{
	return [NSSet setWithObject:@"myArray"];
}

myArray is the instance variable property of the array

The corresponding key method is

- (BOOL)hideSomething
{
	return [self.myArray count] > 3;
}

Consider that the method starts with a lowercase letter,
but the letter after keyPathsForValuesAffecting in the other method is a capital letter!

now enter hideSomething in the key path of the hidden binding of your UI element.

This works also for example with an image


+ (NSSet *)keyPathsForValuesAffectingMainImage
{
	return [NSSet setWithObject:@"imageStatus"];
}


- (NSImage *)mainImage
{
	if (self.imageStatus == 0)
		return [NSImage imageNamed:@"blueImage"]; 
    else if (self.imageStatus == 1)
        return [NSImage imageNamed:@"greenImage"];
    else
        return nil;
}


imageStatus is an integer instance variable property
the key mainImage will be bound to the key path of the value property of an NSImageView object

Hi Stefan,

Thank you for this detailed answer! How much time does it require to gain your knowledge of cocoa? I’m a bit afraid to know the answer – are you a pro developer or just an enthusiastic amateur?

The problem is that good programers don’t spend too much time with ASOC and turn themselves to Objective-C. But I’m not a good programer and stick to ASOC :slight_smile:

I’ll see if I can transfer this code into something working.

Thank you very much again!

Regards,

I regard myself as an enthusiastic amateur, I learned Cocoa/Objective-C as a normal foreign language.

You’re right. I’m using ASOC only for Apple Events to communicate between applications.
Although ASOC is a pretty clever Cocoa bridge, there are too many restrictions in comparison to native C/Objective-C