我已经实现了comboBoxWillPopUp
委托方法,但是当我打开 NSComboBox 的弹出窗口时它永远不会被调用。
其他委托方法,例如comboBoxSelectionDidChange
在同一类中实现的,按预期调用,因此组合框似乎已正确设置。
我尝试删除项目的派生数据以确保编译新实现的方法,但这没有任何区别。如果我在方法的第一行设置断点,它永远不会被命中。
我过去错过了明显的事情,并怀疑现在就是这种情况。知道它是什么吗?
根据 uchuugaka 的要求,一些代码:
组合框是一个出口:
@property (nonatomic, retain) IBOutlet NSComboBox *cmbSubject;
它的控制器正式实现了 NSComboBoxDelegate 协议(等等):
@interface EditorController : NSWindowController <NSComboBoxDelegate, NSComboBoxDataSource, NSTextViewDelegate, NSTextStorageDelegate, NSTabViewDelegate, NSDrawerDelegate, NSTableViewDelegate, NSTableViewDataSource, NSWindowDelegate >
组合框委托在控制器的 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...
}
控制器实现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];
}