Я использую простой контроллер отображения поиска - PullRequest
0 голосов
/ 08 марта 2012

Я использую простой контроллер отображения поиска. Я получаю эту ошибку, я понятия не имею. Вот этот код, пожалуйста, помогите !!!!!

- (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;
}

Ошибка выглядит следующим образом:

2012-03-08 15: 37: 18.905 SearchViewController [1082: fe03] * Ошибка подтверждения в - [UISearchResultsTableView _createPreparedCellForGlobalRow: withIndexPath:], /SourceCache/UIKit_Sim/UIKit-19.m.3/U 2012-03-08 15: 37: 18.907 SearchViewController [1082: fe03] * Завершение приложения из-за необработанного исключения «NSInternalInconsistencyException», причина: «UITableView dataSource должен вернуть ячейку из tableView: cellForRowAtIndexPath: '

Ответы [ 3 ]

7 голосов
/ 15 мая 2013

вместо: UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: @ "cell"];

Попробуйте это: UITableViewCell * cell = [self.tableView dequeueReusableCellWithIdentifier: @ "cell"];

Результат поиска в любом случае представляет новый вид таблицы, и в этом случае он не может идентифицировать предыдущий идентификатор, так как старый вид таблицы не рассматривается.

4 голосов
/ 09 марта 2012

Причина в том, что «источник данных UITableView должен возвращать ячейку из tableView: cellForRowAtIndexPath:», как вы мягко объяснили себе, прежде чем задавать вопрос. Посмотрите на верхнюю часть этого метода, когда вы просите свое табличное представление удалить из очереди многоразовую ячейку

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

Подумайте о том, что произойдет, если в табличном представлении нет ранее созданных ячеек, которые можно использовать бесплатно. И когда вы создаете свой UITableViewController, ему определенно нечего вам предложить, он пуст. И это возвращает ноль.

Поэтому добавьте следующую строку чуть ниже строки, где вы просите удалить ее из очереди, и создайте «совершенно новую» ячейку, если табличное представление не может предоставить вам слово «used».

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

Вы используете @ "cell" в качестве идентификатора ячейки, поэтому рассмотрите возможность создания хотя бы локальной переменной CellIdentifier, чтобы избежать двойного ввода "магической" строки. Взгляните на Руководство по программированию табличного представления , так как повторное использование ячеек является наиболее важной функцией при построении табличного представления. Удачи!

2 голосов
/ 17 января 2013

Я столкнулся с этой проблемой некоторое время назад, исправил ее в одном месте, забыл об этом, и мне пришлось заново открыть решение.

Мое решение состоит в том, чтобы не использовать tableView, переданный в качестве аргумента для tableView:cellForRowAtIndexPath:, а вместо этого использовать tableView, принадлежащий классу tableViewController, в который входит.

в следующем примере, который совсем недавно изменился, так что условие conditionThatDoesntMatterForThisExample теперь возвращало немного другой результат, чем раньше, я обнаружил (или заново открыл, если хотите), что dequeueResuableCellWithIdentifier: возвращал хорошую ячейку в первый случай всегда, но только возвращение хорошей ячейки, когда tableView не был searchResultsTableView для второго вызова.

и ответ заключается в том факте, что tableView в моем tableViewController в моей раскадровке содержит прототип ячеек, которые я хочу использовать, а tableView, представленный searchResultsTableView, не имеет!

- (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];
    }
...