7
votes

I'm using a UISearchDisplayController in my app. When the user selects an item in the search results returned I deactivate the UISearchDisplayController. Deactivating the controller clears the text the user has typed. I want to keep it there. I try to assign the text back into the UISearchBar by setting it again after the controller has been deactivated. The text does appear in the search bar but this will cause the UISearchDisplayController to active again even though I have disable the delegate! This issue only happens on iOS 7. Before iOS7, the code below works charmingly.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSUInteger row = [indexPath row];
NSString *term = [keywordSuggestion objectAtIndex:row];

[search resignFirstResponder];
[self handleSearchForTerm:term];
}

-(void)handleSearchForTerm:(NSString *)searchTerm {

[searchDisplayController setActive:NO animated:YES]; //searchbar text will be lost

searchDisplayController.delegate = nil;
search.text = term;
searchDisplayController.delegate = self;
}

Is there are a way that I can set the text of the UISearchBar without having the UISearchDisplayController that's associated with become active?

1

1 Answers

1
votes

Here is an example of some working code:

#import "RBTableViewController.h"

@interface RBTableViewController () <UISearchDisplayDelegate>

@end

@implementation RBTableViewController {
    UISearchBar *_searchBar;
    UISearchDisplayController *_searchController;
    NSMutableArray *_searchResults;
    NSMutableArray *_model;
    NSString *_cachedSearchTerm;
}

- (NSMutableArray *)currentModel {
    return _searchController.isActive ? _searchResults : _model;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    _searchResults = [[NSMutableArray alloc] init];
    _model = [[NSMutableArray alloc] init];

    for (int i = 0; i < 10; i++) {
        [_model addObject:[NSString stringWithFormat:@"item %d", i]];
    }

     _searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 44)];
    _searchController = [[UISearchDisplayController alloc] initWithSearchBar:_searchBar contentsController:self];
    _searchController.searchResultsDataSource = self;
    _searchController.searchResultsDelegate = self;
    _searchController.delegate = self;
    [_searchController.searchResultsTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"];
    self.tableView.tableHeaderView = _searchBar;
}

- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
    controller.searchBar.text = _cachedSearchTerm;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    if (tableView == _searchController.searchResultsTableView) {
        _cachedSearchTerm = _searchBar.text;
        [_searchController setActive:NO animated:YES];
        [self filterResults:_cachedSearchTerm];
    }
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [[self currentModel] count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
    cell.textLabel.text = [self currentModel][indexPath.row];
    return cell;
}

- (void)filterResults:(NSString *)searchTerm {
    [_searchResults removeAllObjects];
    [_searchResults addObjectsFromArray:[_model filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF contains[s] %@", searchTerm]]];
    [_searchController.searchResultsTableView reloadData];
}

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
    [self filterResults:searchString];
    return YES;
}

- (void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller {
    if (_cachedSearchTerm) {
        controller.searchBar.text = _cachedSearchTerm;
    }
}

@end