我正在尝试使用completes
== YES,没有按钮和numberOfVisibleItems
== 0来创建NSComboBox的效果(例如,尝试在iTunes中填写相册或艺术家获取信息窗口。)
为了实现这一点,我正在使用NSTextField控件,该控件在-controlTextDidChange:
上自动填充以调用-[NSTextField complete:]
,从而触发委托方法:
- (NSArray *)control:(NSControl *)control
textView:(NSTextView *)textView
completions:(NSArray *)words
forPartialWordRange:(NSRange)charRange
indexOfSelectedItem:(NSInteger *)index;
我已经正确地工作了,唯一的问题是下拉显示的副作用。我想压制它,但我还没有看到这样做的方法。我已经搜索了文档,Internet和Stack Overflow,但没有成功。
我更喜欢委托方法,但我愿意继承子类,如果这是唯一的方法。我瞄准Lion,如果它有帮助,所以解决方案不需要向后兼容。
答案 0 :(得分:4)
要解决这个问题,我不得不在盒子外思考一下。我没有使用内置的自动完成机制,而是建立了自己的机制。这并不像我原先认为的那样艰难。我的-controlTextDidChange:
看起来像这样:
- (void)controlTextDidChange:(NSNotification *)note {
// Without using the isAutoCompleting flag, a loop would result, and the
// behavior gets unpredictable
if (!isAutoCompleting) {
isAutoCompleting = YES;
// Don't complete on a delete
if (userDeleted) {
userDeleted = NO;
} else {
NSTextField *control = [note object];
NSString *fieldName = [self fieldNameForTag:[control tag]];
NSTextView *textView = [[note userInfo] objectForKey:@"NSFieldEditor"];
NSString *typedText = [[textView.string copy] autorelease];
NSArray *completions = [self comboBoxValuesForField:fieldName
andPrefix:typedText];
if (completions.count >= 1) {
NSString *completion = [completions objectAtIndex:0];
NSRange difference = NSMakeRange(
typedText.length,
completion.length - typedText.length);
textView.string = completion;
[textView setSelectedRange:difference
affinity:NSSelectionAffinityUpstream
stillSelecting:NO];
}
}
isAutoCompleting = NO;
}
}
然后我实现了另一种我以前没有意识到的委托方法(可以说是这个难题的缺失部分)。
- (BOOL)control:(NSControl *)control
textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector {
// Detect if the user deleted text
if (commandSelector == @selector(deleteBackward:)
|| commandSelector == @selector(deleteForward:)) {
userDeleted = YES;
}
return NO;
}
更新:简化和更正的解决方案
它现在不会跟踪用户输入的最后一个字符串,而是检测用户何时删除。这可以直接而不是迂回的方式解决问题。