Search code examples
macosautocompletenscombobox

How to autocomplete values on NSComboBox


I'm developing an app for MacOS X in Xcode5

I want to autocomplete option typed on textfield when user types or deletes text, for instance if user types "Me" then Mexico option is displayed on list of options, so far this is my code:

@interface ComboNSObject()<NSComboBoxCellDataSource, NSComboBoxDataSource, NSComboBoxDelegate>{
    NSArray *datos;
}

@property (weak) IBOutlet NSComboBox *myCombo;

@end


@implementation ComboNSObject

-(void)awakeFromNib{
    datos = [[NSArray alloc]initWithObjects:@"Mexico",@"Guatemala",@"USA",@"Chile",@"Argentina", nil];

    [_myCombo addItemsWithObjectValues:datos];

}


- (NSString *)comboBox:(NSComboBox *)comboBox completedString:(NSString *)partialString
{
    for (NSString *dataString in datos) {
        NSLog(@"encontrado: %@", [dataString commonPrefixWithString:partialString options:NSCaseInsensitiveSearch]);
    }
    return @"";
}


@end

I already set delegate and datasource of _myCombo and also of its NSComboBoxCell on my NSObjectController but nothing happens, what's the proper code for showing my autocompletion


Solution

  • Gonna share an example I hope this helps:

    #import "AppDelegate.h"
    @interface AppDelegate() <NSComboBoxDataSource, NSComboBoxDelegate, NSControlTextEditingDelegate>{
    
        NSMutableArray      *itemsCombo;
        NSMutableArray      *filteredItemsCombo;
    
    }
    
    @property (weak) IBOutlet NSComboBox *myComboBox;
    
    @end
    
    
    @implementation AppDelegate
    
    - (void)applicationDidFinishLaunching:(NSNotification *)aNotification{
    
        itemsCombo = [NSMutableArray arrayWithObjects:@"Dog",@"Cat",@"Worm",@"Wolf",@"Werewolf",@"Lion",@"Beast", nil];
        filteredItemsCombo = [[NSMutableArray alloc]initWithArray:itemsCombo];
    
    
        _myComboBox.usesDataSource  = YES;
        _myComboBox.completes       = YES;
        _myComboBox.dataSource      = self;
        _myComboBox.delegate        = self;
    }
    
    
    - (NSInteger)numberOfItemsInComboBox:(NSComboBox *)aComboBox{
    
        return filteredItemsCombo.count;
    }
    
    
    - (id)comboBox:(NSComboBox *)aComboBox objectValueForItemAtIndex:(NSInteger)index{
    
        return filteredItemsCombo[index];
    }
    
    
    - (NSUInteger)comboBox:(NSComboBox *)aComboBox indexOfItemWithStringValue:(NSString *)string{
    
        return [filteredItemsCombo indexOfObject:string];
    }
    
    
    -(void)comboBoxWillPopUp:(NSNotification *)notification{
        [self resultsInComboForString:((NSComboBox *)[notification object]).stringValue];
    }
    
    
    -(BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector{
    
        NSComboBox *comboBox = (NSComboBox *) control;
    
        if (comboBox == _myComboBox && (commandSelector == @selector(insertNewline:) ||
                                        commandSelector == @selector(insertBacktab:) ||
                                        commandSelector == @selector(insertTab:))){
            if ([self resultsInComboForString:comboBox.stringValue].count == 0 ||
                 filteredItemsCombo.count == itemsCombo.count) {
                comboBox.stringValue = itemsCombo[0];
            }
    
        }
    
        return NO;
    }
    
    
    - (NSString *)comboBox:(NSComboBox *)aComboBox completedString:(NSString *)string {
    
    
        NSArray  *currentList = [NSArray arrayWithArray:itemsCombo];
    
        NSEnumerator *theEnum = [currentList objectEnumerator];
        id eachString;
        NSInteger maxLength = 0;
        NSString *bestMatch = @"";
        while (nil != (eachString = [theEnum nextObject]) )
        {
            NSString *commonPrefix = [eachString
                                      commonPrefixWithString:string options:NSCaseInsensitiveSearch];
            if (commonPrefix.length >= string.length &&
                commonPrefix.length > maxLength)
            {
                maxLength = commonPrefix.length;
                bestMatch = eachString;
    
                break;
            }
        }
    
        [self resultsInComboForString:string];
    
        return bestMatch;
    }
    
    -(NSArray *)resultsInComboForString:(NSString *)string{
        [filteredItemsCombo removeAllObjects];
    
        if (string.length == 0 || [string isEqualToString:@""] || [string isEqualToString:@" "]) {
            [filteredItemsCombo addObjectsFromArray:itemsCombo];
        }
        else{
            for (int i = 0; i < itemsCombo.count; i++) {
    
                NSRange searchName  = [itemsCombo[i] rangeOfString:string options:NSCaseInsensitiveSearch];
                if (searchName.location != NSNotFound) { [filteredItemsCombo addObject:itemsCombo[i]]; }
    
            }
        }
    
    
        [_myComboBox reloadData];
    
        return filteredItemsCombo;
    }
    
    @end