我有一个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:
没有被调用,这是我在用户选择标记字段时所期望的。
答案 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;
}
答案 2 :(得分:-1)
这可能是因为“enter”键可能会将令牌字段的事件发送到它的操作,其中“tab”键只是向其添加文本。您可以尝试将-isContinuous属性设置为YES,并查看是否获得了所需的结果。