I'm working on a project which would be ideally suit Cocoa bindings for the UI but I'm having an issue binding the value of an object property and can't find a suitable solution. The object is as follows:
typedef enum tagCSQuality {
kQualityBest = 0,
kQualityWorst = 1
} CSQuality;
@interface CSProfile : NSObject {
NSString *identifier;
NSString *name;
CSQuality quality;
}
In the XIB, I have an object controller whose content object is bound to a "currentSelection" property of the window controller which is an instance of the above object. I've then bound the name and identifier which all work as expected but I cannot see how I can bind the enums.
Ideally I would like an NSPopupButton to display "Best" and "Worst" and pick the correct enum value. I have updated the enum to have an explicit numeric value and I believe that I need a value transformer to convert the values but I'm stuck on exactly how this could be implemented.
Can anyone help me out or point me in the right direction?
Thanks, J
You can use an NSValueTransformer
for this.
Since the enumeration values are integers only, they are encapsulated in an NSNumber
object.
An valid transformer could look like the following.
+(Class)transformedValueClass {
return [NSString class];
}
-(id)transformedValue:(id)value {
CSQuality quality = [value intValue];
if (quality == kQualityBest)
return @"Best";
else if (quality == kQualityWorst)
return @"Worst";
return nil;
}
This can be bound to the Selected Value binding of the NSPopupButton
.
If you want to create a bidirectional binding (i.e. be able to select something in the NSPopupButton
you have to add the following code for the reverse transformation:
+(BOOL)allowsReverseTransformation {
return YES;
}
-(id)reverseTransformedValue:(id)value {
if ([@"Worst" isEqualToString:value])
return [NSNumber numberWithInt: kQualityWorst];
else if ([@"Best" isEqualToString:value])
return [NSNumber numberWithInt: kQualityBest];
return nil;
}
An enum is not an object. Cocoa bindings are a way to connect model objects to view objects.
If you are using Interface Builder, you can embed enum represented integer for each NSMenuItem items through property panel. Then select NSPopUpButton and specify binding 'selected tag' to the property with key path.
In this example, assume, IB's file owner is CSProfile. Prepare NSPopUpButton with two NSMenuItem items and tag them with 0(kQualityBest) and 1(kQualityWorst). Then navigate 'selected tag' of NSPopUpButton and check bind to 'File's owner'(CSProfile) with Model Key Path 'quality'.
@interface CSProfile : NSObject {
NSString *identifier;
NSString *name;
CSQuality quality;
}
@property (assign) CSQuality quality;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With