Search code examples
iphoneobjective-cinitializationuisearchdisplaycontroller

How to preload or initialize a search using UISearchDisplayController?


I added a UISearchDisplayController to my UITableViewController in InterfaceBuilder. It was very easy to get it working by adding a searchBar: searchBar textDidChange: searchText method that regenerates the data array for the table and calls reloadData.

But I would like to have the previous search show the next time the users touches in the search bar since it is much easier to touch the (X) and clear it than type it in again. But I cannot get it to do it. Below is the code I've tried:

- (void) searchBar: (UISearchBar *) searchBar textDidChange: (NSString *) searchText {
    if( searchText && [searchText length] > 0 ) {
        self.displayedRows = [[NSMutableArray initWithCapacity: 1];
        for( NSString *l in self.allRows ) {
            NSRange r = [l rangeOfString: searchText];
            if( r.location != NSNotFound )
                [self.displayedRows addObject: l];
        }
        [self.searchDisplayController.searchResultsTableView reloadData];
    }
}

- (void) searchDisplayControllerWillBeginSearch: (UISearchDisplayController *) controller {
    if( self.lastSearch && [self.lastSearch length] > 0 ) {
        controller.searchBar.text = self.lastSearch;
        [controller.searchResultsTableView reloadData];
    }
}

- (void) searchDisplayControllerWillEndSearch: (UISearchDisplayController *) controller {
    self.lastSearch = controller.searchBar.text;
    self.displayedRows = self.allRows;
    [self.tableView reloadData];
}

The last search text is appropriately in the search bar the next time I touch the search and I was surprised that the 'cursor' is even positioned at the end but the search results are not shown, just the darkened view of the original contents like the search field was empty. As soon as I type a character the search results are updated.

I've tried putting the equivalent of [self.searchDisplayController.searchResultsTableView reloadData] into each of:

searchDisplayControllerDidBeginSearch: (UISearchDisplayController *) controller
searchDisplayController: (UISearchDisplayController *) controller didLoadSearchResultsTableView: (UITableView *) tableView
searchDisplayController: (UISearchDisplayController *) controller willShowSearchResultsTableView: (UITableView *) tableView
searchDisplayController: (UISearchDisplayController *) controller didShowSearchResultsTableView: (UITableView *) tableView

But it made no difference... just blank until I type something.

Does anyone have any ideas how to get a preloaded search result?


Solution

  • You need something like this:

    - (void) searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller {
        if(lastSearch.length > 0) {
            NSLog(@"In searchDisplayControllerDidBeginSearch");
            [self.searchDisplayController.searchBar setText:lastSearch];
        }
    }
    

    If you need to make further changes, I suggest opening up the UIKit headers UISearchBar.h and UISearchDisplayController.h and looking at what you can overload and where. Also, NSLog is your friend =)

    Also

    Just to explain what is going on and how this is different from ...searchBar.text = lastSearch, setText forces textDidChange to register, which in turn redoes the search, and subsequently has a call to shouldReloadTableForSearchString. Just changing the text without using setText (for some reason) doesn't trigger textDidChange.