3

Assuming I have an NSObject subclass representing a country, e.g.

@interface CountryInfo : NSObject

@property (nonatomic, retain) NSString *countryName;

My model contains an NSMutableArray of CountryInfos. I want to bind the array to an NSComboBox. The combo box should display the country name, and allow the user to select a country.

So, I set up my .xib like so:

CountryArrayController (NSArrayController)

ContentArray

  • Bind to: File's Owner > Model Key Path: self.model.countries

NSComboBox

Content

  • Bind to: CountryArrayController > Controller Key: arrangedObjects

Content Values

  • Bind to: CountryArrayController > Controller Key: arrangedObjects > Model Key Path: countryName

So far, so good. Now, how to bind the Value of the NSComboBox? The documentation states:

"An NSString or NSNumber that specifies the value of the NSComboBox."

What does this mean? I note that I can bind this to an NSString on my model, and it will reflect the selected countryName. But I want to bind to the CountyInfo object itself! Whether directly, or through binding to the selection on my array controller: how can I set this up?

TheNextman
  • 12,428
  • 2
  • 36
  • 75
  • Have you tried using an NSValueTransformer? – macandyp May 16 '13 at 18:32
  • Hi @macandyp, yes a NSValueTransformer would indeed work and I can get the same behaviour by binding on the string value and manually converting in code. It just seems bizarre that I have to write extra code to achieve this, and can't just bind to the object (which is what I am used to). Thanks! – TheNextman May 16 '13 at 19:37
  • 1
    I agree it's a bit weird. I know that if you bind to content, and not bind content values, it will invoke the description of your class to populate the strings for the combo box. I don't know if that helps you, though. – macandyp May 16 '13 at 20:06

2 Answers2

10

I was approaching this wrong - the correct control to use was NSPopUpButton rather than NSComboBox.

NSComboBox has a different behaviour because it needs to support the scenario where the user directly enters text. NSPopUpButton is designed to only work with a predefined set of values and behaves as expected vis-a-vis it's "selection" bindings.

TheNextman
  • 12,428
  • 2
  • 36
  • 75
1

This issue doesn't seem to have a simple solution, here is the one I found, implementing a NSArrayController category :

@interface NSArrayController( ComboBoxCompatibility )
@property(readwrite )NSString *firstSelectedObject;
@end

And for the getters and setters :

@implementation NSArrayController (ComboBoxCompatibility)
-(NSString *)firstSelectedObject
{
    return [[self selectedObjects] firstObject];
}
-(void)setFirstSelectedObject:(NSString *)firstSelectedObject
{
    NSUInteger idx = [[self arrangedObjects] indexOfObject:firstSelectedObject];
    [self setSelectionIndex:idx];
}
@end

You can then bind the value of the NSComboBox to your array controller's firstSelectedObject as soon as the objects in it implement copyWithZone: you can also modify the above code if the objects aren't strings but have a single property, "name" for example that you display in the combo box list by replacing [self arrangedObjects] with [[self arrangedObjects] valueForKey:@"name"] in the setter and [[[self arrangedObject] firstObject] valueForKey:@"name"] in the getter

piero B
  • 37
  • 6