0
votes

I'm using a simple search display controller. I'm getting this error i have no idea. Here is the code plsss help n thanks!!!!!

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSInteger rows = 0;

    if([tableView isEqual:self.searchDisplayController.searchResultsTableView])
    {
        rows = [self.searchResults count];     
    }
    else
    {
        rows = [self.allItems count];
    }

    return rows;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath    *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];

    if([tableView isEqual:self.searchDisplayController.searchResultsTableView])
    {
        cell.textLabel.text = [self.searchResults objectAtIndex:indexPath.row];
    }
    else
    {
        cell.textLabel.text = [self.allItems objectAtIndex:indexPath.row];
    }

    return cell;
    NSLog(@"the contents of cell are :%@",cell.textLabel.text);
}

-(void) filterContentsForSearchText:(NSString *)searchText scope:(NSString *)scope
{
    NSPredicate *resultsPredicate = [NSPredicate predicateWithFormat:@"SELF contains[cd]  %@",searchText];
    self.searchResults = [self.allItems filteredArrayUsingPredicate:resultsPredicate];
}


//UISearchDisplayController delegate methods
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller    shouldReloadTableForSearchString:(NSString *)searchString
{
    [self filterContentsForSearchText:searchString scope: [[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex: [self.searchDisplayController.searchBar selectedScopeButtonIndex]]];

    return YES;
}

-(BOOL)searchDisplayController:(UISearchDisplayController *) controller shouldReloadTableForSearchScope:(NSInteger)searchOption
{
    [self filterContentsForSearchText:[self.searchDisplayController.searchBar text] scope:[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:searchOption]];

    return YES;
}

The error is as follows:

2012-03-08 15:37:18.905 SearchViewController[1082:fe03] * Assertion failure in -[UISearchResultsTableView _createPreparedCellForGlobalRow:withIndexPath:], /SourceCache/UIKit_Sim/UIKit-1912.3/UITableView.m:6072 2012-03-08 15:37:18.907 SearchViewController[1082:fe03] * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'

3
Have you found any solution for your problem? I'm having a similar problem and I'm really thinking that thats because I didn't link correctly the prototype cell with the searchResultsTableViewjMelnik

3 Answers

6
votes

Instead of: UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];

Try this: UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"cell"];

Search result presents a new tableview anyway and for that case it cannot identify the previous identifier,since the old tableview is not in the question.

4
votes

The reason is that 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:' as you gently explained yourself before asking the question. So look at the top of this method when you ask your table view to dequeue reusable cell

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];

Think about what would happen if table view has no earlier created cells which are free to use. And when you create your UITableViewController it definitely has nothing to offer you, it's empty. And it returns nil.

So add the following line just below the line where you ask to dequeue it and create "brand new" cell if table view can't provide you with "used".

if (!cell) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"] autorelease]; //if you compile with ARC, drop autorelease
}

You use @"cell" as your cell id, so consider making at least the local variable CellIdentifier to avoid double typing "magic" string. And take a look at a Table View Programming guide cause reusing of cells is the most essential feature when constructing your table view.Good luck!

2
votes

i ran into this problem myself a while back, fixed it in one place, forgot about it, and had to re-discover again the solution.

my solution is to not use the tableView passed as an arg to tableView:cellForRowAtIndexPath:, but to rather use the tableView that belongs to the enclosing tableViewController class.

in the following example, which had just recently changed so that conditionThatDoesntMatterForThisExample was now returning a slightly different result than it used to, i discovered (or re-discovered, if you prefer) that dequeueResuableCellWithIdentifier: was returning a good cell in the first case always, but only returning a good cell when the tableView was not the searchResultsTableView for the second call.

and the answer lies in the fact that the tableView in my tableViewController in my storyboard has the prototype cells i want to use, where the tableView represented by searchResultsTableView does not!

- (UITableViewCell *)tableView:(UITableView*)tableView
         cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
    BOOL isSearching = tableView == self.searchDisplayController.searchResultsTableView;
    UITableViewCell* cell;
    BOOL isAnchor = conditionThatDoesntMatterForThisExample;

    if (isAnchor)
    {
        cell = [self.tableView dequeueReusableCellWithIdentifier:PlainCell];
    }
    else
    {
        cell = [tableView dequeueReusableCellWithIdentifier:ReplyCell];
    }