2010-06-08 2 views

ответ

6

NSTokenField является подклассом NSTextField. Нет простого, прямого способа напрямую манипулировать выбором этих классов (кроме -selectText :, который выбирает все).

Чтобы сделать это, когда он становится первым ответчиком, вам нужно подкласс NSTokenField (не забудьте установить класс поля в вашем XIB к тому из пользовательского подкласса) и переопределить -becomeFirstResponder следующим образом:

- (BOOL)becomeFirstResponder 
{ 
    if ([super becomeFirstResponder]) 
    { 
     // If super became first responder, we can get the 
     // field editor and manipulate its selection directly 
     NSText * fieldEditor = [[self window] fieldEditor:YES forObject:self]; 
     [fieldEditor setSelectedRange:NSMakeRange([[fieldEditor string] length], 0)]; 
     return YES; 
    } 
    return NO; 
} 

Этот код сначала проверяет, отвечает ли супер «да» (и становится первым ответчиком). Если это так, мы знаем, что у него будет редактор полей (экземпляр NSText), выбор которого может непосредственно манипулировать. Поэтому мы получаем его редактор полей и устанавливаем его выбранный диапазон (я положил точку вставки в конце с диапазоном {lastchar, nolength}).

Чтобы сделать это, когда поле завершения редактирования (возврат, табулируя из и т.д.), переопределить -textDidEndEditing: как это:

- (void)textDidEndEditing:(NSNotification *)aNotification 
{ 
    [super textDidEndEditing:aNotification]; 
    NSText * fieldEditor = [[self window] fieldEditor:YES forObject:self]; 
    [fieldEditor setSelectedRange:NSMakeRange([[fieldEditor string] length], 0)]; 
} 

В этом случае, когда пользователь заканчивает редактирование, этот метод позволяет супер делает свое дело, тогда он смотрит, будет ли он еще первым ответчиком. Если это так, он делает то же самое, что и выше: помещает вставку карат в конце поля.

Примечание. Это поведение не является стандартным и является неожиданным. Используйте экономно.

+0

Спасибо, Джошуа, это работает! Но как насчет поведения при нажатии ENTER. Попытка переопределить «keyDown:» не работает. Любая идея отключить это поведение? – Robert

+0

Я обновил ответ с помощью -textDidEndEditing: case. Поскольку оба метода в конечном итоге вызывают одно и то же, он начинает выглядеть как работа для рефакторинга. Я бы вытащил код редактора полей в свой собственный метод (например, -adjustSelection) и назвал это, чтобы сделать код более читаемым и менее повторяющимся. –

+0

TextDidEndEditing: case не работает правильно для меня. Допустим, что после последнего токена установите текстовый курсор и не начинайте вводить какие-либо символы, а просто нажмите RETURN. В этом случае выбраны все теги, хотя я добавил ваше предложение textDidEndEditing:. Любые идеи почему? – Robert