NSTokenField不会在模糊时检查令牌

时间:2011-08-16 12:24:19

标签: objective-c cocoa nstokenfield

我有一个NSTokenField,允许用户选择联系人(就像在Mail.app中一样)。所以NSTextField绑定到我的model.recipient实例变量中的数组。

用户现在可以从自动完成列表中选择一个条目,例如Joe Bloggs: joe@blogs.com,一旦他点击 Enter ,就会显示令牌(Joe Bloggs)model.recipients现在包含BBContact条目。

现在,如果用户开始键入某些键(因此显示建议),然后点击 Tab 而不是输入带有完成文本(Joe Bloggs: joe@bloggs.com)值的令牌,并且没有调用NSTokenFieldDelegate方法,因此我可以响应此事件。 model.recipient条目现在包含NSString而不是BBContact条目。

奇怪的是委托方法tokenField:shouldAddObjects:atIndex:没有被调用,这是我在用户选择标记字段时所期望的。

enter image description here

3 个答案:

答案 0 :(得分:6)

在委托上按Tab键调用isValidObject,因此在其中为NSTokenField返回NO,但如果没有字母数字字符则返回YES,否则用户将无法远离字段(字符串包含不可见)基于存在多少令牌的unicode字符)

我可以提出的不那么脆弱的实施是:

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

答案 1 :(得分:0)

我能够使用@ 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

答案 2 :(得分:-1)

这可能是因为“enter”键可能会将令牌字段的事件发送到它的操作,其中“tab”键只是向其添加文本。您可以尝试将-isContinuous属性设置为YES,并查看是否获得了所需的结果。