当@ Sign触发自动完成时,Cocoa NSTextField自动完成功能无法正常工作

时间:2014-03-01 02:19:42

标签: objective-c macos cocoa

我在NSTextField中实现自动完成时遇到问题。我希望在用户输入+或@时触发自动完成功能。 (我以todo.txt格式自动完成项目和上下文。)

我对其进行编码的方式,当用户键入+时,它的工作方式完全符合预期,但当用户键入@时,它的行为不正常。我现在对其进行编码的方式,我的- (NSArray *)textView:(NSTextView *)textView completions:(NSArray *)words forPartialWordRange:(NSRange)charRange indexOfSelectedItem:(int *)index方法不会返回任何自动完成建议,因为charRange不仅包含@符号,还包含@符号前面的单词和空格。

如果我更改此方法的工作方式,并且不要尝试将charRange与我的关键字匹配,那么当@触发自动完成时,@符号之前的单词和空格也会被替换,当我只是希望更换@符号。

我已经将NSTextField子类化,并实现了几种方法来自定义内置的自动完成功能。我正在返回自动填充建议的自定义列表。我的代码如下。我已经阅读了Apple文档和谷歌搜索了几天试图解决这个问题。我认为我的做法可能是错误的,而且我愿意把这个问题抛在脑后,从更好的方法开始。

如果我可以修复传递给构建自动完成列表的方法的部分单词范围,那么我的方法会起作用。我知道Text View对象中有一个rangeForUserCompletion方法,但我不知道如何使其工作。请帮忙!

#import <Cocoa/Cocoa.h>

@interface TETextField : NSTextField

@end

#define COMPLETION_DELAY (0.25)

@implementation TETextField

NSTimer *_completionTimer;

- (BOOL)acceptsFirstResponder {
    return YES;
}

- (NSArray *)textView:(NSTextView *)textView completions:(NSArray *)words forPartialWordRange:(NSRange)charRange indexOfSelectedItem:(int *)index

    // this will be defined elsewhere
    NSArray *keywords = @[@"@home", @"@work", @"@phone", @"+Report", @"+Presentation"];

    NSString *partialString = [[textView string] substringWithRange:charRange];
    NSLog(@"partialString: %@", partialString);

    NSMutableArray *matches = [[NSMutableArray alloc] init];
    for (NSString *string in keywords) {
        if ([string rangeOfString:partialString
                          options:NSAnchoredSearch | NSCaseInsensitiveSearch
                            range:NSMakeRange(0, [string length])].location != NSNotFound)
        {
            [matches addObject:string];
        }
    }

    [matches sortUsingSelector:@selector(compare:)];
    return matches;
}

-(void)keyUp:(NSEvent *)event {
    if ([[event characters] isEqualToString:@"@"] || [[event characters] isEqualToString:@"+"]) {
        [self startCompletionTimer];
    } else {
        [self stopCompletionTimer];
    }
    [super keyUp:event];
}

- (void)doCompletion:(NSTimer *)timer {
    [self stopCompletionTimer];
    [self.currentEditor complete:self];
}

- (void)startCompletionTimer {
    [self stopCompletionTimer];
    _completionTimer = [NSTimer
                        scheduledTimerWithTimeInterval:COMPLETION_DELAY target:self
                        selector:@selector(doCompletion:) userInfo:nil repeats:NO];
}

- (void)stopCompletionTimer {
    [_completionTimer invalidate];
    _completionTimer = nil;
}

@end

0 个答案:

没有答案