燮pressing文本完成下拉一个的NSTextField [英] Suppressing the text completion dropdown for an NSTextField

查看:114
本文介绍了燮pressing文本完成下拉一个的NSTextField的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建一个NSComboBox与效果完成 = = YES,NO按钮和 numberOfVisibleItems == 0(为例,尝试在专辑或艺术家填充在iTunes的获取信息窗口)。

I'm trying to create the effect of an NSComboBox with completes == YES, no button, and numberOfVisibleItems == 0 (for an example, try filling in an Album or Artist in iTunes's Get Info window).

要做到这一点,我使用的NSTextField控件,它自动填充在 -controlTextDidChange:调用 - [完整的NSTextField:] ,这将触发委托方法:

To accomplish this, I'm using an NSTextField control, which autocompletes on -controlTextDidChange: to call -[NSTextField complete:], which triggers the delegate method:

- (NSArray *)control:(NSControl *)control
            textView:(NSTextView *)textView
         completions:(NSArray *)words
 forPartialWordRange:(NSRange)charRange
 indexOfSelectedItem:(NSInteger *)index;

我已经得到这个工作正常,唯一的问题是一个下拉列表显示的副作用。我想燮preSS,但我还没有看到一个方法来做到这一点。我已经冲刷的文档,互联网和堆栈溢出,但没有成功。

I've gotten this working correctly, the only problem being the side effect of a dropdown showing. I would like to suppress it, but I haven't seen a way to do this. I've scoured the documentation, Internet, and Stack Overflow, with no success.

我preFER一个委托方法,但我开到子类,如果这是唯一的方法。我瞄准狮子,万一有帮助,这样的解决方案并不需要向后兼容。

I'd prefer a delegate method, but I'm open to subclassing, if that's the only way. I'm targeting Lion, in case it helps, so solutions don't need to be backward compatible.

推荐答案

要解决这个问题,我得想箱子一点点之外。除了使用内置的自动完成的机制,我建我自己的。这不是一样坚韧,因为我原本以为这将是。我的 -controlTextDidChange:看起来像这样:

To solve this, I had to think outside the box a little. Instead of using the built-in autocomplete mechanism, I built my own. This wasn't as tough as I had originally assumed it would be. My -controlTextDidChange: looks like so:

- (void)controlTextDidChange:(NSNotification *)note {
    // Without using the isAutoCompleting flag, a loop would result, and the
    // behavior gets unpredictable
    if (!isAutoCompleting) {
        isAutoCompleting = YES;

        // Don't complete on a delete
        if (userDeleted) {
            userDeleted = NO;
        } else {
            NSTextField *control = [note object];
            NSString *fieldName = [self fieldNameForTag:[control tag]];
            NSTextView *textView = [[note userInfo] objectForKey:@"NSFieldEditor"];

            NSString *typedText = [[textView.string copy] autorelease];
            NSArray *completions = [self comboBoxValuesForField:fieldName
                                                      andPrefix:typedText];

            if (completions.count >= 1) {
                NSString *completion = [completions objectAtIndex:0];

                NSRange difference = NSMakeRange(
                                         typedText.length,
                                         completion.length - typedText.length);
                textView.string = completion;
                [textView setSelectedRange:difference
                                  affinity:NSSelectionAffinityUpstream
                            stillSelecting:NO];
            }
        }

        isAutoCompleting = NO;
    }
}

然后我又实现委托方法我是不是previously意识到(缺少的一块拼图,可以这么说)。

And then I implemented another delegate method I wasn't previously aware of (the missing piece of the puzzle, so to speak).

- (BOOL)control:(NSControl *)control
       textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector {
    // Detect if the user deleted text
    if (commandSelector == @selector(deleteBackward:)
        || commandSelector == @selector(deleteForward:)) {
        userDeleted = YES;
    }

    return NO;
}

更新:简体和修正的解决方案

现在不跟踪用户输入的最后一个字符串,代替检测当用户删除。这解决了问题,在直接,而不是迂回,方式。

It now doesn't track the last string the user entered, instead detecting when the user deleted. This solves the problem in a direct, rather than roundabout, manner.

这篇关于燮pressing文本完成下拉一个的NSTextField的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆