Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSTextField autocomplete

Does anyone know of any class or lib that can implement autocompletion to an NSTextField?

I'am trying to get the standard autocmpletion to work but it is made as a synchronous api. I get my autocompletion words via an api call over the internet.

What have i done so far is:

- (void)controlTextDidChange:(NSNotification *)obj
{
    if([obj object] == self.searchField)
    {
        [self.spinner startAnimation:nil];
        [self.wordcompletionStore completeString:self.searchField.stringValue];

        if(self.doingAutocomplete)
            return;
        else
        {
            self.doingAutocomplete = YES;
            [[[obj userInfo] objectForKey:@"NSFieldEditor"] complete:nil];
        }
    }
}

When my store is done, i have a delegate that gets called:

- (void) completionStore:(WordcompletionStore *)store didFinishWithWords:(NSArray *)arrayOfWords
{
    [self.spinner stopAnimation:nil];
    self.completions = arrayOfWords;
    self.doingAutocomplete = NO;
}

The code that returns the completion list to the nstextfield is:

- (NSArray *)control:(NSControl *)control textView:(NSTextView *)textView completions:(NSArray *)words forPartialWordRange:(NSRange)charRange indexOfSelectedItem:(NSInteger *)index
{
    *index = -1;
    return self.completions;
}

My problem is that this will always be 1 request behind and the completion list only shows on every 2nd char the user inputs.

I have tried searching google and SO like a mad man but i cant seem to find any solutions..

Any help is much appreciated.

like image 785
Rasmus Styrk Avatar asked Nov 29 '12 19:11

Rasmus Styrk


1 Answers

Instead of having the boolean property doingAutocomplete, make the property your control that made the request. Let's call it autoCompleteRequestor:

@property (strong) NSControl* autoCompleteRequestor;

So where you set your current property doingAutocomplete to YES, instead store a reference to your control.

- (void)controlTextDidChange:(NSNotification *)obj
{
    if([obj object] == self.searchField)
    {
        [self.spinner startAnimation:nil];
        [self.wordcompletionStore completeString:self.searchField.stringValue];

        if(self.autoCompleteRequestor)
            return;
        else
        {
            self.autoCompleteRequestor = [[obj userInfo] objectForKey:@"NSFieldEditor"];
        }
    }
}

Now when your web request is done, you can call complete: on your stored object.

- (void) completionStore:(WordcompletionStore *)store didFinishWithWords:(NSArray *)arrayOfWords
{
    [self.spinner stopAnimation:nil];
    self.completions = arrayOfWords;
    if (self.autoCompleteRequestor)
    {
       [self.autoCompleteRequestor complete:nil];
       self.autoCompleteRequestor = nil;
    }
}
like image 160
Fruity Geek Avatar answered Sep 22 '22 06:09

Fruity Geek