I've implemented the comboBoxWillPopUp
delegate method, but it is never called when I open the NSComboBox's popup.
Other delegate methods, such as comboBoxSelectionDidChange
, implemented in the same class, are called as expected, so the comboBox seems to have been set up appropriately.
I tried deleting the project's derived data to ensure that the newly implemented method gets compiled, but this made no difference. If I set a breakpoint in the first line of the method, it is never hit.
I've missed obvious things in the past and suspect that's the case now. Any idea what it is?
Per uchuugaka's request, some code:
The comboBox is an outlet:
@property (nonatomic, retain) IBOutlet NSComboBox *cmbSubject;
Its controller formally implements the NSComboBoxDelegate protocol (among others):
@interface EditorController : NSWindowController <NSComboBoxDelegate, NSComboBoxDataSource, NSTextViewDelegate, NSTextStorageDelegate, NSTabViewDelegate, NSDrawerDelegate, NSTableViewDelegate, NSTableViewDataSource, NSWindowDelegate >
The comboBox delegate is assigned in the controller's awakeFromNib:
- (void) awakeFromNib {
// other stuff...
[self.cmbSubject setUsesDataSource:YES];
[self.cmbSubject setDataSource:self];
[self.cmbSubject setDelegate:self]; // controller (self) assigned as delegate
[self.cmbSubject setCompletes:YES];
// Tell the combobox to reload; otherwise it looks OK but thinks it's empty.
// (Data source caches are in DataSourceCoordinator, which should be set up before this controller.)
[self.cmbSubject reloadData];
// other stuff...
}
The controller implements comboBoxWillPopUp:
- (void) comboBoxWillPopUp:(NSNotification *)notification {
// If breakpoint is added here, it is never hit.
NSComboBox *cmb = [notification object];
// Determine the maximum height available to the cmb popup...
CGFloat heightAvailable;
CGFloat heightScreen = [NSScreen mainScreen].frame.size.height;
CGFloat heightOriginCMB = cmb.frame.origin.y + self.window.frame.origin.y; // origin is from bottom
// ...which usually will be the space below the cmb...
if (heightOriginCMB >= heightScreen/2)
heightAvailable = heightOriginCMB;
// ...unless user has positioned the window very low, in which case the cmb will present the popup on top if necessary.
else
heightAvailable = heightScreen - heightOriginCMB;
// Determine the maximum number of items that can be displayed.
NSInteger iMaxItemsToDisplay = heightAvailable / [cmb itemHeight]; // truncate to whole number
// Ensure the max is at least 3, just in case.
// (If window contents are rearranged so that cmb origin is no longer relative to Editor window, or if item height is set to some large number, this could be an issue.)
if (iMaxItemsToDisplay < 3)
iMaxItemsToDisplay = 3;
// Set cmb's numberOfVisibleItems, which acts as a maximum.
[cmb setNumberOfVisibleItems:iMaxItemsToDisplay];
}