Чтобы решить эту проблему, мне пришлось немного нестандартно подумать. Вместо того, чтобы использовать встроенный механизм автозаполнения, я создал свой собственный. Это было не так сложно, как я изначально предполагал. Мой -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;
}
Обновление: упрощенное и исправленное решение
Теперь он не отслеживает последнюю введенную пользователем строку, а определяет, когда пользователь удалил. Это решает проблему прямым, а не окольным путем.