UISearchDisplayController does not update search results

I have the following search setup in my app:

- (UISearchBar*)searchBar
{

    if (!_searchBar) {

        _searchBar = [[UISearchBar alloc] init];
        _searchBar.delegate = self;
        _searchBar.placeholder = kSearchBarPlaceHolder;
    }
    return _searchBar;
}
- (UISearchDisplayController*)searchBarDisplayContr
{

    if (!_searchBarDisplayContr) {

        _searchBarDisplayContr = [[UISearchDisplayController alloc] initWithSearchBar:self.searchBar contentsController:self];
        _searchBarDisplayContr.delegate = self;
        _searchBarDisplayContr.searchResultsDataSource = self.tableView.dataSource;
        _searchBarDisplayContr.searchResultsDelegate = self.tableView.delegate;
        _searchBarDisplayContr.searchResultsTableView.backgroundColor = [UIColor clearColor];
        _searchBarDisplayContr.searchResultsTableView.separatorStyle = UITableViewCellSeparatorStyleNone;

    }

    return _searchBarDisplayContr;
}

- (NSMutableArray *)searchResults
{

    if (!_searchResults) {
        _searchResults = [NSMutableArray arrayWithCapacity:_restaurants.count];
    }

    return _searchResults;
}

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{

    [self.searchResults removeAllObjects];

    [self.restaurants enumerateObjectsUsingBlock:^(Restaurant *restaurant, NSUInteger idx, BOOL *stop) {
        if ([scope isEqualToString:@"All"] || [restaurant.name isEqualToString:scope]) {

            NSRange range = [restaurant.name rangeOfString:searchText
                                                   options:(NSCaseInsensitiveSearch | NSDiacriticInsensitiveSearch)];


            if (range.length > 0) {
                [self.searchResults addObject:restaurant];
            }
       }

    }];



}

- (BOOL)searchDisplayController:(UISearchDisplayController*)controller shouldReloadTableForSearchString:(NSString*)searchString
{
    [self filterContentForSearchText:searchString
                               scope:@"All"];



    dispatch_async(dispatch_get_main_queue(), ^(void) {
        for (UIView *v in controller.searchResultsTableView.subviews) {
            if ([v isKindOfClass:[UILabel class]]) {
                ((UILabel *)v).text = kSearchResultsTableViewNoResultsLabel;
                ((UILabel *)v).font = [UIFont mediumFontOfSize:20.0f];
                ((UILabel *)v).textColor = [UIColor blackColor];
                break;
            }
        }
    });


    return YES;
}



- (BOOL)searchDisplayController:(UISearchDisplayController*)controller shouldReloadTableForSearchScope:(NSInteger)searchOption
{
    [self filterContentForSearchText:[self.searchBarDisplayContr.searchBar text]
                               scope:@"All"];

    return YES;
}

But for some reason when I search the searchResultsTableView is not updated / cellForRowAtIndexPath is not called. The tableView delegates and DataSource is setup in my storyboard.

Any ideas why this is happening?

UPDATE:

 [self.tableView registerClass:[RestaurantsCell class] forCellReuseIdentifier:cellIdentifier];

    [self.searchBarDisplayContr.searchResultsTableView registerClass:[RestaurantsCell class] forCellReuseIdentifier:cellIdentifier];


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section
{
    if (tableView == self.searchBarDisplayContr.searchResultsTableView) {

        return [self.searchResults count];

    } else {       

           return [self.restaurants count];


    }
    return 0;
}

- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{

    RestaurantsCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    Restaurant *restaurant;

    if (tableView == self.searchBarDisplayContr.searchResultsTableView) {

        if (self.searchResults.count > 0) {

            restaurant = self.searchResults[indexPath.row];


        }


    } else {   

 if (self.restaurants.count > 0) {     

          restaurant = self.restaurants[indexPath.row];

}

    }


    if (restaurant) {

        cell.titleLabel.text = restaurant.name;
    }
    return cell;
}

Upvotes: 0

Views: 1477

Answers (1)

michaelsnowden
michaelsnowden

Reputation: 6192

This is the offending line:

RestaurantsCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

Should be:

RestaurantsCell *cell = [self.tableView dequeueReusableCellWithIdentifier:cellIdentifier];

Explanation:

If the tableView turns out to be your search results table view, then trying to dequeue a cell with an identifier won't work because it doesn't have prototype cells. Therefore, you have to use self.tableView

Also, your code can be cleaned up a lot:

- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section
{

    return (tableView == self.tableView) ? self.restaurants.count : self.searchResults.count;
}

- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{

    RestaurantsCell *cell = [self.tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    Restaurant *restaurant = (tableView == self.tableView) ? self.restaurants[indexPath.row] ? self.searchResults[indexPath.row];
    }

    cell.titleLabel.text = restaurant.name;
    return cell;
}

Edit Check out this example

Upvotes: 2

Related Questions