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
NSComboBox
Content
Content Values
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?
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.
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
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