iPhone autocomplete class

While working on the Cashbase iPhone project ( CashbaseHq ), I found myself longing for an autocomplete feature, but could not find anything on the web. So I decided to build my own. The functionality is identical to the way autocomplete is used on the web. Upon typing a text in the text field, a list with suggestions appears bellow it. Selecting an item from the suggestions list will hide the list and add the word in the textfield.

This is how it looks in our app (for space reasons we have designed the suggestion list to be displayed above the field that requires autocomplete, but you can easily display it below – just see the demo app)

How to use:

Import the Autocomplete.h file

#import "Autocomplete.h"

Prepare the target UITextField for autocomplete by disabling the iPhone’s default autocomplete feature. You usually do this in the viewDidLoad method.

//disable the iPhone's default autocomplete feature
textField.autocorrectionType = UITextAutocorrectionTypeNo;
 
//create the Autocomplete class and initialize it with some data
autocomplete = [[Autocomplete alloc] initWithArray:[[NSArray alloc] initWithObjects:@"apples", @"oranges", @"bananas", @"peaches", @"grapes", @"blackberries", @"strawberies", @"watermelons", @"mangos", @"pears", @"lemons", nil]];

Now, when the text in the text field has changed (ie: in the EditingChanged handler), just call the GetSuggestions method, which will return an array of strings that match the parameter passed

NSArray *suggestions = [autocomplete GetSuggestions:textField.text];

You can do whatever you want with these suggestions, I displayed them in  a table view and when the user taps a cell, the text is added to the text field (see attached demo project)

Autocomplete Demo Application

Autocomplete Source

19 comments

  1. Wow, this is a godsend, thanks!

    Quick question: whats the easiest way to make this case insensitive?

    • Hi Louis,

      actually it was supposed to be case insensitive, but there was a small bug. Thanks for bringing it to my attention – I have fixed the issue, please try redownloading the source – it should work as expected now.

  2. Thank you so much for this class. It works excellent and I use it to every project where I need a autocompletetion functionality.

    Greetings from Sweden!

  3. Very cool !!!
    Thank you so much for sharing.

    Nice work.

  4. You’re not handle memory management correctly in your example code:

    //create the Autocomplete class and initialize it with some data
    autocomplete = [[Autocomplete alloc] initWithArray:[[NSArray alloc] initWithObjects:@”apples”, @”oranges”, @”bananas”, @”peaches”, @”grapes”, @”blackberries”, @”strawberies”, @”watermelons”, @”mangos”, @”pears”, @”lemons”, nil]];

    Either use [NSArray arrayWithObjects:…] or send an autorelease at the end

  5. Actually, your actual code also contains a significant memory leak:

    – (void)AddCandidate:(NSString *)candidate
    {
    //Is the candidate already in the list?
    for (int i = 0; i < [candidates count]; i++)
    {
    if ([[candidates objectAtIndex:i] isEqualToString:candidate])
    {
    return;
    }
    }

    //Add the new candidate
    [candidates addObject:[candidate copy]]; <— candidate is overretained
    [candidates sortUsingSelector:@selector(compare:)];
    }

  6. sorry to keep complaining, but in fact your code is not correct…

    take the array “a”, “b”, “c”, “d”. if i do getsuggestions with the string “d”, i don’t get “d” back.

  7. here’s a fix btw:

    change both lines that read
    int position = (start + end)/2 to
    int position = ((end – start) == 1) ? end : (start + end) / 2;

  8. sorry, that last one is not quite right yet:

    introduce a BOOL up = YES;
    whenever you do an end = position you set up = NO
    whenever you do a start = position you set up = YES

    int position = ((end – start) == 1) ? (up ? end : start) : (start + end) / 2;

    this still doesnt work when you only have 2 elements in your initial array but that case is not relevant for me

    • Hi Joris,

      thank you for feedback

      Much to my shame, I didn’t profile the demo app before uploading it as I was in a hurry. But you were right with regards to the leaks. They’re fixed now

      I have also updated the code to use predicates and now it should work as expected in all cases.

  9. This is pretty simple – thanks for that.

    One thing that works, but is a bit weird is that it adds the table as a subview every time the text changes. I profiled this, it doesn’t actually end up creating more subviews. But I don’t think that’s the way add subview is supposed to be used – at the very least, remove the subview first.

  10. In – (NSMutableArray *)GetSuggestions:(NSString *)root method,

    if you assign
    int end = [candidates count] – 1;
    You can’t never suggest the last element of array.

    edit each occurences in the method in int end = [candidates count];// – 1;

    Hope I don’t miss anything!
    Thank you for Autocomplete class! It is very good!

    Giuseppe

  11. Thank you for this class. It’s really useful.

    I would suggest you to make this diacritic insensitive as well. It would be very useful to all the international visitors of your site, like myself. 😉

    Sergio

  12. May the sun shine warm upon your face,
    and rains fall soft upon your fields.

  13. Thanks for this post. I referenced it while searching for UITextField in-line autocomplete approaches. I eventually came up with my own, HTAutocompleteTextField:

    https://github.com/hoteltonight/HTAutocompleteTextField

  14. […] http://www.radulucaciu.ro/iphone-autocomplete-class/5/ 本条目发布于 2013 年 5 月 5 日。属于 iOS 分类。作者是 admin。 […]

  15. How to develop an iPhone application…

    iPhone autocomplete class « Radu Lucaciu…

Leave a Reply

Your email address will not be published. Required fields are marked *