NSTokenField не проверяет токен на размытие - PullRequest
7 голосов
/ 16 августа 2011

У меня есть NSTokenField, который позволяет пользователю выбирать контакты (как в Mail.app).Таким образом, NSTextField привязан к массиву в моей model.recipient переменной экземпляра.

Теперь пользователь может выбрать запись из списка автозаполнения, например, Joe Bloggs: joe@blogs.com, и, как только он нажмет Введите , отобразится токен (Joe Bloggs), а model.recipients теперь содержит BBContact запись.

Теперь, если пользователь начинает вводить какие-то клавиши (чтобы отобразились предложения), а затем нажимает Tab вместо Введите токен со значением текста завершения (Joe Bloggs: joe@bloggs.com) создан, и методы NSTokenFieldDelegate не были вызваны, чтобы я мог ответить на это событие.Запись model.recipient теперь содержит NSString вместо записи BBContact.

Любопытно, что метод делегата tokenField:shouldAddObjects:atIndex: не вызывается, что я и ожидал, когда пользователь выходит изполе токена.

enter image description here

Ответы [ 3 ]

6 голосов
/ 05 февраля 2014

Нажатие табуляции вызывает isValidObject для делегата, поэтому верните NO для NSTokenField в нем, однако вы хотите вернуть YES, если в нем нет буквенно-цифровых символов, иначе пользователь не сможет сфокусироваться вне поля (строка содержит невидимый символы Юникода в зависимости от количества токенов)

Менее хрупкая реализация, которую я мог бы придумать:

- (BOOL)control:(NSControl *)control isValidObject:(id)token
{
    if ([control isKindOfClass:[NSTokenField class]] && [token isKindOfClass:[NSString class]])
    {
        if ([token rangeOfCharacterFromSet:[NSCharacterSet alphanumericCharacterSet]].location == NSNotFound) return YES;
        return NO;
    }
    return YES;
}
0 голосов
/ 14 февраля 2014

Мне удалось решить проблему, используя предложения @ valexa.В случае размытия с TAB я должен пройти через все записи и найти мои контактные объекты для любых строк.

- (BOOL)control:(NSControl *)control isValidObject:(id)token{
    if ([control isKindOfClass:[NSTokenField class]] && [token isKindOfClass:[NSString class]])
    {
        NSTokenField *tf = (NSTokenField *)control;

        if ([token rangeOfCharacterFromSet:[NSCharacterSet alphanumericCharacterSet]].location == NSNotFound){
            return YES;
        } else {

            // We get here if the user Tabs away with an entry "pre-selected"
            NSMutableArray *set = @[].mutableCopy;
            for(NSObject *entry in tf.objectValue){

                GSContact *c;
                if([entry isKindOfClass:GSContact.class]){
                    c = (GSContact *)entry;
                }

                if([entry isKindOfClass:NSString.class]){

                    NSString *number = [[(NSString *)entry stringByReplacingOccurrencesOfString:@">" withString:@""]
                                        componentsSeparatedByString:@"<"][1];
                    c = [self findContactByNumber:number];
                }

                if(c) [set addObject:c];
            }

            [control setObjectValue:set];
        }
    }
    return YES;
}

enter image description here

0 голосов
/ 09 ноября 2011

Это может быть потому, что клавиша "enter" может отправлять событие поля токена в его действие, когда клавиша "tab" просто добавляет к нему текст.Вы можете попытаться установить для свойства -isContinuous значение YES и посмотреть, получите ли вы желаемые результаты.

...