Запретить выбор всех токенов в NSTokenField

Есть ли способ запретить NSTokenField выбирать все при нажатии клавиши ENTER или при обращении к первому респонденту, возможно, с помощью клавиши TAB?


person Robert    schedule 08.06.2010    source источник


Ответы (1)


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;
}

Этот код сначала проверяет, отвечает ли super "да" (и становится первым респондентом). Если это так, мы знаем, что у него будет редактор полей (экземпляр 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)];
}

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

Обратите внимание, это поведение нестандартно и неожиданно. Используйте экономно.

person Joshua Nozzi    schedule 09.06.2010
comment
Спасибо, Джошуа, это работает! А как же поведение при нажатии ENTER. Попытка переопределить keyDown: не работает. Есть идеи отключить это поведение? - person Robert; 10.06.2010
comment
Я обновил ответ с помощью -textDidEndEditing: case. Поскольку оба метода вызывают одно и то же, это начинает выглядеть как работа по рефакторингу. Я бы вытащил код редактора поля в отдельный метод (например, -adjustSelection) и вызвал бы его, чтобы сделать код более читабельным и менее повторяющимся. - person Joshua Nozzi; 10.06.2010
comment
Случай textDidEndEditing: у меня работает некорректно. Допустим, установите текстовый курсор после последнего токена и не начинайте вводить какие-либо символы, а просто нажмите RETURN. В этом случае выбраны все теги, хотя я добавил ваше предложение textDidEndEditing :. Есть идеи, почему? - person Robert; 11.06.2010
comment
Кажется, если поле токена - единственное, что в окне принимает первый респондент, он не откажется от него. Я протестировал код с другим текстовым полем, чтобы можно было протестировать переход с табуляции и обратно. Удалите оператор if, чтобы всегда можно было манипулировать редактором поля. Кажется, работает нормально. - person Joshua Nozzi; 12.06.2010
comment
Я добавил сюда загружаемый подключаемый класс: joshua.nozzi.name/source/nonselectingtokenfield - person Joshua Nozzi; 16.06.2010