Home > Cocoa, iPhone SDK > How to add a search bar to your table view, and integrate it in your section indexes?

How to add a search bar to your table view, and integrate it in your section indexes?

Assume you have a table view filled with objects. Assume you have sections for these objects, and you have setup the section indexes. Until this point, nothing which cannot be found in SDK’s documentation.

Assume now you want to add a search bar to your table view. What do you do? To answer this question, we will start from source code available to all of us, implementing the required table view with section indexes, we shall use the TableViewSuite’s 3rd example, I have named “3_SimpleIndexedTableView” (you can download the tutorial package there).

From this base, I will indicate the updates necessary to display a search bar in the first row. I will do this the fast way, so it may not be really nice. And I will not implement everything required to do search and display search results, you will have to look at documentation for this (this will essentially consist in connecting the search bar with required objects and delegates, providing content for search results).

So, what do we do to the TableViewSuite’s 3rd example:

  1. We change the numberOfSectionsInTableView: method in order to return one row more (you guess? …the row for the search bar naturally!):
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // The number of sections is the same as the number of titles in the collation.
    return [[collation sectionTitles] count] + 1; // CHANGE: add one for the search cell
    }
  2. We update (a little) the tableView:numberOfRowsInSection: and tableView:titleForHeaderInSection: methods in order to have it return good number of rows for the good sections:
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (section == 0) return 1; // CHANGE: return one for the search cell
    // The number of time zones in the section is the count of the array associated with the section in the sections array.
    NSArray *timeZonesInSection = [sectionsArray objectAtIndex:section - 1];
    return [timeZonesInSection count];
    }
    - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    if (section == 0) return nil;
    return [[collation sectionTitles] objectAtIndex:section - 1];

    }
  3. Finally, we update the most important method, I have named tableView:cellForRowAtIndexPath: :
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    // CHANGE: add the search cell
    if ([indexPath indexAtPosition:0] == 0) {
    static NSString *CellIdentifier = @"SearchCell";
    UITableViewCell *searchBarCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    [searchBarCell addSubview:[[UISearchBar alloc] initWithFrame:searchBarCell.frame]];
    return searchBarCell;
    }

    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
    // Get the time zone from the array associated with the section index in the sections array.
    NSArray *timeZonesInSection = [sectionsArray objectAtIndex:indexPath.section - 1];
    // Configure the cell with the time zone's name.
    TimeZoneWrapper *timeZone = [timeZonesInSection objectAtIndex:indexPath.row];
    cell.textLabel.text = timeZone.localeName;
    return cell;
    }
  4. Like I told before, you should then get the searchBarCell connected to the good objects to have it up and working. One last tip, I use the UISearchDisplayController class and connect them both in this way:
    UISearchDisplayController *sdc = [[UISearchDisplayController alloc] initWithSearchBar:sb contentsController:self];
    [sdc setValue:self forKey:@"searchResultsDataSource"];
    [sdc setValue:self forKey:@"searchResultsDelegate"];

Uh oh, I almost forgot to give you the best tip! How to have the “search” tool icon (what’s this tool’s name in English?) in your section indexes? Just follow the guide… (’cause this cannot be found in the doc, but you may find it elsewhere on the net, like I did – however it’s too long ago, I have not kept the source link).

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return [[NSArray arrayWithObject:@"{search}"] arrayByAddingObjectsFromArray:[collation sectionIndexTitles]];
}

If you have a problem, you can’t make it work in your code, do not hesitate to ask… I have tried this code changes and it worked for me, but I may have forget something!

[Edited] As requested, please find the xCode project there.

About these ads
  1. howcr
    17/09/2009 at 3:44 pm

    Hi,

    This is helpful. Can you make the xCode project available? I’m having a problem putting it all together but I would like to learn from it.

  2. rchampourlier
    21/09/2009 at 6:15 pm

    Hi! Thank you for the comment. I’ll update my xCode project and share it on the blog (if possible). Stay connected for the update!

    • 24/09/2009 at 6:08 pm

      Hi. thanks for the tutorial. would you be able to do a tutorial on Core Data and the UISearch. using the photolocations sample code provided by Apple?

      Chris

      • rchampourlier
        03/10/2009 at 7:11 am

        Sorry for the late answer. In fact, I did not use Core Data for my iPhone’s apps yet. But as soon as I get to do it, you may indeed have a tutorial. However, since I’m already having some hard time getting the xCode project for this tip done… it may take some time too!

  3. Bud
    12/10/2009 at 6:00 pm

    Aloha,
    Thanks for your tutorial. I have an iPhone app that uses a plist to populate the first table view, so I’ve made arrays for both the keys and their associated values. I’ve also incorporated search functions, complete with adding the search bar (using IB), but could not figure out how to add the search icon to the index. I changed my sectionIndexTitlesForTableView: method to mirror what you have above, and while it works with respect to showing the search icon, if effectively moves the association between the index items and their sections down by one. In other words, when using the index, stopping at the search icon stops at the ‘#’ section, stopping at ‘#’ shows the ‘A’ section, stopping at ‘A’ shows the ‘B’ section and so on. This is only an irritation at this point, but I would like to figure out what is going on.

    Is there anything you can tell me at this point, or do you need any further information?

    • rchampourlier
      13/10/2009 at 10:02 pm

      Hhmm… have you added the search bar as the first cell of the table view? or just as another view next to your table view? Because you must have the search bar as a cell. In fact, it has to be the first and only cell of the first section. I think your problem is the first section remained the same, while you added a section index before its own…

  4. Suresh
    30/10/2010 at 6:30 am

    I m getting the following error in the console when i run ur downloaded code…

    -[NSArray objectAtIndex:]: index 1 beyond bounds [0 .. 0]‘

    What must be the problem…???

    • rchampourlier
      31/10/2010 at 6:57 am

      I’m looking into it, come back soon!

    • rchampourlier
      31/10/2010 at 7:57 am

      I found the problem and kind of corrected it (it was within original source code, so I may have changed somehow the results, but my objective remains functional). I uploaded it here, and updated the link above too.
      Enjoy, and do not hesitate to share with me if you got it working in your own app. I just looked again my example and saw the search field was being overwritten by the index table, which I would like to prevent… but I’ve no time now to investigate. So if you can improve this, do not hesitate to share with me, I’d be pleased!

  5. Adam
    11/12/2010 at 10:37 am

    Nice work! But I’m not clear on where you’re declaring the UISearchDisplayController, and how you’re connecting it to the UISearchBar. I’m especially interested to see how you hooked it up given all the trouble I’ve had with zombies… Could you update your sample code to include that stuff? Thanks!

    • rchampourlier
      13/12/2010 at 2:25 pm

      Thanks for the comment. I’m sorry I’ve not much time at the moment (working on several projects… iPhone apps, startup preparation…), but be sure I’ll look at your question and answer it as soon as possible! Come back soon to check the answer ;)

  6. Adam
    13/12/2010 at 7:54 pm

    I think I’ve gotten my controllers sorted out. As for the index overlapping the search box, this is what works best for me: [(id)searchBar setContentInset:UIEdgeInsetsMake(5, 0, 5, 35)];

  7. David
    24/02/2011 at 4:22 pm

    I have implemented a TableView and search which used a plist to populate the tableView.I am now amending the code and trying to use static data from CoreData.I can load the records into allNames (Dictonary) and names (MutableDictionary).However when resetSearch is called the program bombs out at the line.

    NSMutableDictionary *allNamesCopy = [self.allNames mutableDeepCopy];

    error is

    unrecognized selector sent to instance 0x643fae0

    This is doing my head in, as I thought I was on the ‘Home straight’ with my first App

  8. Nekbeth
    29/03/2011 at 5:51 am

    Hi, great tutorial!! I was wondering if you can help on an Array of Dictionaries. Most tutorials have 1 dictionary with many arrays, my case is the opposite. I m just looking to retrieve the titles of my objects, their on strings with key “Title” inside the dictionaries. How would you call them and hold them into a local variable called “listOfmovies”

    Thank you

  9. Lux interior
    • rchampourlier
      28/09/2011 at 4:43 pm

      OK, I uploaded the file again. I hope this is the good one. Keep me posted if it seems it does not match!

  10. 15/11/2011 at 10:49 am
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: