Question

I have an NSArrayController that I fill in the awakeFromNib method. The data has the keys: id, name, and description. I have a ComboBox and a TextField bound to the NSArrayController the first with the name and the second with the id. If I change the selection in the ComboBox I want the value in the TextField to change, and vice-versa. I read the docs for TextField and ComboBox bindings, but I didn't understand how to achieve this.

Was it helpful?

Solution

The trick here is that you need somewhere else to put the value of the NSComboBox. The NSArrayController is fine for providing the stock values to the NSComboBox, but you can type arbitrary values into an NSComboBox that might not be in the NSArrayController's contentArray, so it's not surprising that you need somewhere else to put the value. I was able to mock this up quickly by just putting a simple value on the AppDelegate like this:

@interface SOAppDelegate : NSObject <NSApplicationDelegate>

@property (assign) IBOutlet NSWindow *window;
// The NSArrayController you were talking about...
@property (assign) IBOutlet NSArrayController* popupValues;    
// The other place to store data...
@property (retain) id comboBoxValue;

@end

Then in the implementation:

@implementation SOAppDelegate

@synthesize window = _window;
@synthesize comboBoxValue = _comboBoxValue;

- (void)dealloc
{
    [_comboBoxValue release];
    _comboBoxValue = nil;
    [super dealloc];
}

-(void)awakeFromNib
{    
    [super awakeFromNib];
    NSMutableDictionary* item1 = [NSMutableDictionary dictionaryWithObjectsAndKeys: 
                                  [NSNumber numberWithUnsignedInteger: 1], @"id", 
                                  @"Item 1 Name", @"name", 
                                  @"Item 1 Description", @"description", 
                                  nil];
    NSMutableDictionary* item2 = [NSMutableDictionary dictionaryWithObjectsAndKeys: 
                                  [NSNumber numberWithUnsignedInteger: 2], @"id", 
                                  @"Item 2 Name", @"name", 
                                  @"Item 2 Description", @"description", 
                                  nil];
    NSMutableDictionary* item3 = [NSMutableDictionary dictionaryWithObjectsAndKeys: 
                                  [NSNumber numberWithUnsignedInteger:3], @"id", 
                                  @"Item 3 Name", @"name", 
                                  @"Item 3 Description", @"description", 
                                  nil];

    NSMutableArray* array = [NSMutableArray arrayWithObjects: item1, item2, item3, nil];
    self.popupValues.content = array;
}

@end

Then for the bindings, I set it up like this:

NSComboBox:

  • Content -> Array Controller.arrangedObjects
  • Content Values -> Array Controller.arrangedObjects.name
  • Value -> App Delegate.comboBoxValue (check Continuously Updates Value if you want the NSTextField to be updated letter-by-letter as you're typing in the NSComboBox)

NSTextField:

  • Value -> App Delegate.comboBoxValue (check Continuously Updates Value if you want the NSComboBox to be updated letter-by-letter as you're typing in the NSTextField)

If you want new values you type in to be added to the array, I'm sorry to say, that's not readily doable with just these two controls and bindings. That's a fair bit more complicated. But the trick for the simple case is that you need some place to store the value other than the NSArrayController you're using to provide pre-loaded values to the NSComboBox.

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