我有一个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:没有被调用,这是我在用户选中标记字段时所期望的.
解决方法
按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; }