7

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

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

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

奇怪的是,委托方法tokenField:shouldAddObjects:atIndex:没有被调用,这是我在用户退出令牌字段时所期望的。

在此处输入图像描述

4

3 回答 3

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;
}
于 2014-02-05T16:39:21.893 回答
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;
}

在此处输入图像描述

于 2014-02-14T13:17:31.573 回答
-1

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

于 2011-11-08T20:00:13.077 回答