Apple方便地创建了一个回调方法,允许您检查添加到NSTokenField的新令牌是否有效:
- (NSArray *)tokenField:(NSTokenField *)tokenField shouldAddObjects:(NSArray *)newTokens atIndex:(NSUInteger)index
我已经实现了这一点,结果证明它非常有效,只有一个例外。如果用户开始键入令牌,但尚未完成令牌的键入,并且用户按下TAB键,则不会调用验证方法。
这意味着我能够确保输入的所有令牌都是有效的,除非用户计算出他们可以按tab键绕过验证。
有人知道处理这种情况的正确方法是什么吗?
我试了一会儿,发现当按下Tab键时,令牌字段调用NSControlTextEditingDelegate协议的control:isValidObject:。因此,您可以实现委托方法,如
- (BOOL)control:(NSControl *)control isValidObject:(id)object
{
NSLog(@"control:%@", control);
NSLog(@"object:%@", object);
return NO;
}
"object"参数是不完整令牌的内容。如果该方法返回NO,则令牌将不会插入到有效令牌的数组中。
我也在努力解决这个问题,发现使用zonble建议的control:isValidObject几乎可以解决问题,但很难根据对象参数确定是返回NO还是YES。据我所知,这个问题仅限于tab键,因此我实现了以下两种方法;
我意识到这非常丑陋,但这是我获得NSTokenField的唯一方法,以避免在选项卡上创建令牌,同时不影响NSToken菲尔德的其他NSTextField行为(例如将光标移动到新位置等)。
- (BOOL)control:(NSControl *)control isValidObject:(id)object
{
if (self.performingTab) {
self.performingTab=NO;
return NO;
} else {
return YES;
}
}
- (BOOL)control:(NSControl *)control textView:(NSTextView *)fieldEditor
doCommandBySelector:(SEL)commandSelector
{
if (commandSelector==@selector(insertTab:)) {
self.performingTab=YES;
}
return NO;
}
我尝试了一种稍微不同的方法,而是注意tab键,将其更改为返回键。此委托方法首先确认它是相关的令牌字段,并检查命令选择器。)
很抱歉把这个答案留给Swift——考虑到这中间的8.5年,希望是允许的
func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool
{
if control == tokenField, // my interested token field
commandSelector == #selector(insertTab(_:))
{
textView.insertNewline(self)
return true
}
return false
}