Question

I've got a very simple problem, but the solution is proving very elusive.

Here's what I have:

typedef { foo, bar, baz} EnumType;

@interface SomeObject: NSObject
@property EnumType someEnumValue;
@end

...and a view with an object_controller and an NSComboBox that should display the string name of the someEnumValue of the [object_controller selection] instance.

I realize that I can't directly access the names of the enum values as strings. I've tried creating an NSArray holding the names of the enum values, and binding the ContentValues property to it - this loads the combo box with the property strings, but I can't find any way to relate the enum value in the selected instance to the values in the combo box.

I've also tried using an NSValueTransformer to translate enum values to NSStrings and vice versa, but for the life of me, I can't get it working: most of these attempts result in a thrown exception.

This trivial task has sucked about three hours out of my life. HELP! Thank you!

Was it helpful?

Solution

There are two approaches that I can think of to solve your problem.

  1. Load the array with strings in the same order as it is in your enum. Since you've got rest of the things working querying the NSComboBox for "indexOfSelectedItem" will give you the exact value of the enum. (Note: This works only if your enum starts from zero. Which I guess is the case while looking at your example.)

  2. Since you have created a class to hold the enum value. Add one more property to it which will hold the name of the enum.. Again query the NSComboBox for indexOfSelectedItem.You can now easily get the associated value by accessing object at given index from the arrangedObjects of arrayController that you are using to bind to the combo box.

OTHER TIPS

Recording my chosen solution for posterity:

In the end, I solved this problem by... not using an enum.

The problem, of course, is that combo boxes expect to be bound to an array of objects (i.e., instances of NSObject), but enums are defined as constant integers (which are primitives).

I'm sure that it's possible to provide some infrastructure to translate enum values to objects, and back again. (Ostensibly, this is what the NSValueTransformer classes do, and it's easy to subclass and design one... but for the life of me, I couldn't find any way of actually binding my NSValueTransformer subclass or an instance of it to the combo box. Documentation for that essential step DOES NOT EXIST. It's pretty crazy - every example I found simply talked about how to subclass it, not how to BIND it. And everything I tried threw an exception.)

In the end, I realized that all of this hard work and translation could be avoided simply by making the enum values into instances of a class.

So with enums, you have to do all of this:

typedef { a, b, c } EnumType;
@interface SomeClass {
    @property EnumType enumValue;
}...

// somewhere else, something like this:
NSMutableArray *enumTypeNames = { @"a", @"b", @"c" };

...and then bind the combo box to the enumTypeNames, and perform some acrobatics to translate enum values to enumTypeNames indices and vice versa.

Or, you can just do this:

@interface EnumClass {
    @property NSString *name;
} ...
@interface SomeClass {
    @property (weak) EnumClass *enumValue;
} ...

// somewhere else:
NSMutableArray *enumValues = [NSMutableArray new];
[enumValues addObject: [EnumClass initWithName: @"a"]];
[enumValues addObject: [EnumClass initWithName: @"b"]];
[enumValues addObject: [EnumClass initWithName: @"c"]];

...and bind the combo box directly to the array (with name specified as the model key path). Much cleaner solution.

I think you can accomplish this using NSValueTransformer.

Try defining your enum like this:

typedef NS_ENUM(NSUInteger, EnumType) {
    foo = 0,
    bar = 1,
    baz = 2
};

Then in your value transformer, treat the input as an NSNumber and call -unsignedIntegerValue. Cast that to your enum type if you want, run it through a switch statement, and return the proper string.

The binding should automatically wrap the enum value as an NSNumber.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top