I have an NSPopupButton whose selection index is bound to a property in an NSWindowController subclass. In IB, the button starts out with a couple items. The property's value comes from NSUserDefaults and might be more than the number of items in the NSPopupButton when it is first instantiated. This causes a blank item to be inserted at the end of the list. If I append items to the button, the automatically-created blank item is still there. But when I make a selection it disappears. If I change the title of the blank item before making a selection the item still disappears.
I've distilled the problem down to this code:
@interface PopUpWindowController : NSWindowController {
NSUInteger popUpValue;
IBOutlet NSPopUpButton *popUp;
}
@property NSUInteger popUpValue; //popUp's Selected Index is bound to this property
-(IBAction)addItemsToPopUp:(id)sender;
-(IBAction)nameBlankItem:(id)sender;
@end
@implementation PopUpWindowController
@synthesize popUpValue;
-(id)init {
if (self = [super initWithWindowNibName:@"PopUpWindow"]) {
popUpValue = 5; //In my real program this comes from NSUserDefaults
}
return self;
}
-(IBAction)addItemsToPopUp:(id)sender {
//Add three items to popUp
NSUInteger lastNewItem = [popUp numberOfItems] + 3;
for (NSUInteger newItem = [popUp numberOfItems]; newItem < lastNewItem; newItem++) {
[popUp addItemWithTitle:[NSString stringWithFormat:@"%d", newItem + 1]];
}
self.popUpValue = 5;
}
-(IBAction)nameBlankItem:(id)sender {
NSArray *items = [popUp itemArray];
for (NSUInteger i = 0; i < [items count]; i++) {
if (![[[items objectAtIndex:i] title] length]) {
//item title is blank so set it to the item number
[[items objectAtIndex:i] setTitle:[NSString stringWithFormat:@"%d", i + 1]];
}
}
}
@end
Here's the popUp's menu when the window first appears (it has three items in IB named "1", "2", & "3"):
Here it is after calling addItemsToPopUp:
Here it is after calling nameBlankItem:
Then I called addItemsToPopUp:
again:
Now I finally make a selection and pop up the menu again:
Where did 4
go?
In my real program, I do want the menu items to be "1".."n" (n being defined by the number of items in a calculated NSArray). I'm open to alternative approaches, but I am hoping the solution continues to use an NSPopupButton.
(In case it matters, I'm using Xcode 3.1.2 under OS X 10.5.8, but also tested with Xcode 3.2 under OS X 10.6.8.)
I solved the problem by binding the NSPopUpButton's Content Values property to an array in my object. So instead of manually manipulating the button's item array in conjunction with whatever Cocoa is doing behind the scenes, I'm in complete control of the contents.