9

Apple 方便地创建了一个回调方法,允许您检查添加到 NSTokenField 的新令牌是否有效:

- (NSArray *)tokenField:(NSTokenField *)tokenField shouldAddObjects:(NSArray *)newTokens atIndex:(NSUInteger)index

我已经实现了这一点,结果证明它工作得很好,除了在一种情况下。如果用户开始键入令牌,但尚未完成键入令牌,并且用户按下 TAB 键,则不调用验证方法。

这意味着我能够确保输入的所有令牌都是有效的,除非用户可以按 Tab 键绕过验证。

有谁知道处理这种情况的正确方法是什么?

4

3 回答 3

7

我试了一会儿,发现在按下 Tab 键时,token 字段调用了 NSControlTextEditingDelegate 协议的 control:isValidObject:。所以你可以实现一个委托方法,比如

- (BOOL)control:(NSControl *)control isValidObject:(id)object
{
    NSLog(@"control:%@", control);
    NSLog(@"object:%@", object);
    return NO;
}

'object' 参数是您的不完整令牌的内容。如果该方法返回 NO,则不会将令牌插入到有效令牌数组中。

于 2011-06-15T14:34:49.717 回答
2

我也在努力解决这个问题,发现使用 zonble 建议的 control:isValidObject 几乎可以解决问题,但是很难根据对象参数确定返回 NO 还是 YES。据我所知,这个问题仅限于制表键,所以我实现了如下一对方法;

我意识到这非常丑陋,但这是我可以让 NSTokenField 避免在选项卡上创建标记同时不影响 NSTokenField 的其他 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;        
}
于 2013-08-28T11:45:31.673 回答
0

我尝试了一种稍微不同的方法,而是注意制表键,将其更改为返回键。这个委托方法首先确认它是相关的令牌字段并检查命令选择器。)

很抱歉在 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
}
于 2020-09-03T04:38:11.933 回答