Возможно, NSTokenField со смешанным вводом токена/строки?

При вводе недопустимого сообщения электронной почты в Mail NSTokenField получите это (сочетание токенов и простых строковых значений):

alt text

Есть ли какой-либо рекомендуемый способ для этого?
Является ли NSTokenField правильным инструментом для этого? Или я буду злоупотреблять им?

В этом конкретном проекте мне нужно разрешить пользователю вводить шаблон имени файла
(есть и другие варианты использования), с поддержкой предопределенных токенов.

Сейчас я требую ввода ввода следующим образом:

Glue Text %[Tag]Other Glue Text%[Another Tag]More Text

Я хотел бы изменить это на какое-то безупречное графическое решение вроде этого: alt text

NSTokenField всегда (!) превращает введенный текст в токены.

Либо я использую неправильные ключевые слова в своих веб-поисках,
или я действительно первый, кто нуждается в этом (смешанном) поведении?!

Я прочитал руководство Apple NSTokenField, но не смог найти никакой информации о моей проблеме.

Ответы

Ответ 1

Вам нужно реализовать метод делегата tokenField:styleForRepresentedObject:, чтобы вернуть либо NSRoundedTokenStyle для токенов, либо NSPlainTextTokenStyle для другого текста. Представляемый объект для токена - это сама маркерная строка, если только ваш делегат не возвращает другие объекты.

Это должно сделать трюк для вашего дела:

- (NSTokenStyle)tokenField:(NSTokenField *)tokenField
 styleForRepresentedObject:(id)representedObject
{
    if ([representedObject rangeOfString: @"%["].location == 0) {
        return NSRoundedTokenStyle;
    } else {
        return NSPlainTextTokenStyle;
    }
}

Ответ 2

Собственно, сначала нужно определить символ токенизации, который в вашем случае будет%

[tokenField setTokenizingCharacterSet:[NSCharacterSet characterSetWithCharactersInString:@"%%"]];

Строка ввода также должна быть изменена:

Клей-текст% [Тег]% Другой клей Текст% [Другой тег]% Больше текста

... так что Cocoa знает, где заканчивается токен.

И если вы хотите, чтобы [Tag] отображался как Tag в поле токена, вам также необходимо реализовать метод tokenField:displayStringForRepresentedObject::

- (NSTokenStyle)tokenField:(NSTokenField *)tokenField
 displayStringForRepresentedObject:(id)representedObject
{
    if ([representedObject rangeOfString: @"["].location == 0) {
        return [(NSString*)representedObject substringWithRange:NSMakeRange(1, [(NSString*)representedObject length]-2)];

    return representedObject;
}

Однако это имеет большой недостаток: если вы скопируете или просто перенесите токен, Cocoa вызовет tokenField:displayStringForRepresentedObject:, а скопированный/перемещенный токен будет изменен на обычный текст Tag вместо токена [Tag].

Если у кого-то есть решение вышеуказанной проблемы, я с удовольствием прочитаю его.