saltwat5r
saltwat5r

Reputation: 1147

iOS UISearchDisplayController doesn't show results

I have a problem with UISearchDisplayController. I added a UITableView to UIViewController using Storyboard. UITableViewDataSource and UITableViewDelegate are connected to myViewController in Storyboard.

I implemented following delegates and datasources in myViewController:

UISearchBarDelegate, UISearchDisplayDelegate, UITableViewDataSource, UITableViewDelegate. Showing all of data in table view works fine, but when I start searching, numberOfRowsInSection: method is called but after that cellForRowAtIndexPath: isn't called, and the searchResultsTableView isn't displayed at all. Can someone help me?

Below is code of UISearchDisplayDelegate and UISearchBarDelegate methods.

EDIT:

static NSString *ProductCellIdentifier = @"TKMProductTableCell";
@interface TKMSearchAllProductsTableVC () <UISearchBarDelegate, UISearchDisplayDelegate, UITableViewDataSource, UITableViewDelegate> {
    UISearchDisplayController *searchDisplayController;
}

@property (nonatomic, strong) NSArray *allProducts;
@property (nonatomic, strong) NSMutableArray *filteredProducts;
@property (nonatomic, strong) UISearchBar *searchBar;

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (tableView == searchDisplayController.searchResultsTableView) {
        return [_filteredProducts count];
    } else {
        return [_allProducts count];
    }
}

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

    TKMProductTableCell *cell = [self.tableView dequeueReusableCellWithIdentifier:ProductCellIdentifier];

    // Configure the cell...
    [self configureProductCell:cell atIndexPath:indexPath inTableView:tableView];

    return cell;
}

- (void)configureProductCell:(TKMProductTableCell *)cell atIndexPath:(NSIndexPath *)indexPath inTableView:(UITableView *)tableView
{
    TKMProduct *product = nil;
    if (tableView == searchDisplayController.searchResultsTableView) {
        product = self.filteredProducts[indexPath.row];
    } else {
        product = self.allProducts[indexPath.row];
    }

    cell.lblTitle.text = product.name;

}
#pragma mark - UISearchBarDelegate
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
    [self.navigationItem setRightBarButtonItem:nil];
    searchBar.showsCancelButton = YES;

    searchBar.autocorrectionType = UITextAutocorrectionTypeNo;

    [searchDisplayController setActive:YES animated:YES];
}

-(void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
    searchBar.showsCancelButton = NO;
}

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
    searchBar.showsCancelButton = NO;

    [searchBar resignFirstResponder];
    [searchDisplayController setActive:NO animated:YES];
    [self dismissViewControllerAnimated:YES completion:nil];
}

#pragma mark - UISearchDisplayDelegate

- (void)filterContentForSearchText:(NSString *)searchText
{
    [self.filteredProducts removeAllObjects];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name contains[c] %@", searchText];
    _filteredProducts = [NSMutableArray arrayWithArray:[_allProducts filteredArrayUsingPredicate:predicate]];
}

- (void)searchDisplayController:(UISearchDisplayController *)controller didShowSearchResultsTableView:(UITableView *)tableView
{
    tableView.backgroundColor = [UIColor redColor];
}

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
    {
    if (![searchString isEqualToString:@""] && searchString != nil) {
        [self filterContentForSearchText:searchString];
        [searchDisplayController.searchResultsTableView setHidden:NO];
    }

    return YES;
}

EDIT 2

This is my code for UISearchDisplayController:

searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:_searchBar contentsController:self];
searchDisplayController.delegate = self;
searchDisplayController.searchResultsDataSource = self;
searchDisplayController.searchResultsDelegate = self;

Here is screenshoot of storyboard connections:
screenshoot of storyboard connections

EDIT 3:

I've just found in Logs that UITableView's frame is CGRectZero in numberOfRowsInSection method:

(lldb) po [searchDisplayController searchResultsTableView]
<UISearchResultsTableView: 0x1368c4a00; frame = (0 0; 0 0); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x1744420d0>; layer = <CALayer: 0x174821e20>; contentOffset: {0, 0}; contentSize: {0, 0}>

(lldb) po [self.searchDisplayController searchResultsTableView]
<UISearchResultsTableView: 0x1368c4a00; frame = (0 0; 0 0); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x1744420d0>; layer = <CALayer: 0x174821e20>; contentOffset: {0, 0}; contentSize: {0, 0}>

(lldb) po self.tableView
<UITableView: 0x136878e00; frame = (0 0; 320 504); clipsToBounds = YES; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x17444dd70>; layer = <CALayer: 0x17422e300>; contentOffset: {0, 0}; contentSize: {320, 117906}>

(lldb) po tableView
<UISearchResultsTableView: 0x1368c4a00; frame = (0 0; 0 0); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x1744420d0>; layer = <CALayer: 0x174821e20>; contentOffset: {0, 0}; contentSize: {0, 0}>

Upvotes: 0

Views: 570

Answers (3)

santibernaldo
santibernaldo

Reputation: 835

Have you registered the class or the custom cell nib to the UISearchDisplayController Table?

I do in that UISearchDisplayController delegate method:

- (void)searchDisplayController:(UISearchDisplayController *)controller
  didLoadSearchResultsTableView:(UITableView *)tableView
{
    [tableView registerClass:[UITableViewCell class]
      forCellReuseIdentifier:CellIdentifier];
}

Upvotes: 0

E-Riddie
E-Riddie

Reputation: 14780

Suggestion

I may be a little bit off topic but you should know this.

Don't use UISearchDisplayController because it won't be stable anymore.

Apple Documentation

Important: UISearchDisplayController is deprecated in iOS 8. (Note that UISearchDisplayDelegate is also deprecated.) To manage the presentation of a search bar and display search results in iOS 8 and later, instead use UISearchController.

Link

Upvotes: 1

Punita
Punita

Reputation: 1387

Have you check what numberOfRowsInSection returns. also check _filteredProducts array size after filterContentForSearchText method execute inside shouldReloadTableForSearchString method. put NSLog inside each method and debug the code.

Try this NSPredicate format string:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like[cd] %@", searchText];

Upvotes: 0

Related Questions