Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 623
LavaSlider Avatar asked Feb 03 '11 01:02

LavaSlider


1 Answers

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.

like image 191
aqua Avatar answered Oct 03 '22 20:10

aqua