7

I'm trying to add a Search Bar to one of my apps that lets a user enter address information, and a tableview appears with the possible results (and a keyboard). Essentially the same functionality provided in the Maps app. Is there an easy way to do this?

enter image description here

It would be nice to have a Current Location default & autocomplete as well, but not necessary. I can build the UI from scratch, but I don't know how to get back the search results. Can I use geocoder and parse the results into a tableview?

Gergo Erdosi
  • 40,904
  • 21
  • 118
  • 94
James Weir
  • 135
  • 1
  • 7

1 Answers1

10

There is a standard component for doing that, called UISearchDisplayController.

It gives you a UISearchBar and a UITableView for displaying the results. Then you can customize the content and the appearance of the table view according to your needs.

In order to get control over the actions performed by such controller you will need to conform to the UISearchDisplayDelegate protocol.

I suggest you to look carefully at the example app you can find on the doc.

EDIT

In order to implement the autocompletion features you can implement the searchDisplayController:shouldReloadTableForSearchString method of the UISearchDisplayDelegate protocol. It will be called at every character typed by the user.

Assuming that you have a CLGeocoder property called geocoder and that you are holding the placemarks into an NSArray property called placemarks, here's an example of how you can achieve a live autocompletion:

-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {      
    [self.geocoder geocodeAddressString:searchString completionHandler:^(NSArray *placemarks, NSError *error) {
            self.placemarks = placemarks;
            [self.searchDisplayController.searchResultsTableView reloadData];
    }];
    return NO;
}

Everytime the input string for the search change, you perform a forward geocoding using such string. In the completionHandler block you assign the newly found placemarks to your placemarks property and reload the table.

Please not that since the search is asynchronous you will take care of reloading the table in the completion handler and return NO in the delegate method. Returning YES will make the table to reload before the search is over, which is not the behaviour you want.

As a final remark, remember that the code I provided is minimal. In a real-world app you'd better take care of the errors the geocoder may run into, such as kCLErrorGeocodeFoundNoResult, kCLErrorGeocodeFoundPartialResult and kCLErrorGeocodeCanceled, documented here.

Gabriele Petronella
  • 106,943
  • 21
  • 217
  • 235
  • That works great for the UI side of things. Any idea on the second part of my question, the search results? I want to be able to start typing in the UISearchBar and have the possible locations show up in the table (I'm assuming using Apple Maps). – James Weir Dec 29 '12 at 09:40
  • Ok, everything is working now, but the results are not what I was hoping for. CLGeocoder doesn't give the greatest of results. For example, searching for "Apple" like I did in the screenshot above yields only 2 hits based on street address. Looking at Apple docs they mention that to find their HQ using CLGeocoder you'd have to search for '1 Infinite Loop, Cupertino, CA'. Is there no way to get the kind of search results that the Maps app yeilds (like in the picture above). The goal was to make location searching easy for the user - not to require precise address info. – James Weir Dec 29 '12 at 23:42
  • You may consider different geocoders. Try to google it, and if you cannot find anything ask another question ;) – Gabriele Petronella Dec 29 '12 at 23:54
  • Thanks for the help. Marking this as resolved since it answered what I was trying to do. – James Weir Dec 30 '12 at 00:29
  • unable to get example app – Patel Jigar Sep 11 '15 at 09:40