Подтвердить что ты не робот

UISearchDisplayController и повреждение прототипа UITableView

У меня есть настройка UIViewController в раскадровке с табличным представлением и UISearchDisplayController.

Я пытаюсь использовать собственную прототипную ячейку из self.tableview(которая связана с основным видом таблицы в раскадровке). Он отлично работает, если self.tableview вернул хотя бы 1 ячейку при загрузке моего представления, но если self.tableview не загружает ячейку (поскольку нет данных), и я загружаю UISearchBar и выполняю поиск, cellForRowAtIndexPath: сбой метода:

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

    [self configureCell:cell atIndexPath:indexPath];
    return cell;
}

-(void)configureCell:(CustomSearchCell *)cell atIndexPath:(NSIndexPath *)indexPath {
    User *user = [self.fetchedResultsController objectAtIndexPath:indexPath];

    cell.nameLabel.text = user.username;
}

Ошибка:

*** Assertion failure in -[UITableViewRowData rectForRow:inSection:heightCanBeGuessed:]
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'request for rect at invalid index path (<NSIndexPath: 0x9ef3d00> {length = 2, path = 0 - 0})

У моего fetchedResultsController, по-видимому, есть данные (1 секция, 2 строки) в точке, на которой вызывается вышеупомянутый метод. Он выходит из строя в строке dequeueReusableCellWithIdentifier.

Любые указатели/идеи? Он должен удалить ячейку прототипа из self.tableview, но я предполагаю, что в self.tableview не было ничего, что было причиной?

4b9b3361

Ответ 1

UISearchDisplayController управляет собственным UITableView (фильтрованной таблицей) в дополнение к вашей основной таблице. Идентификатор ячейки в отфильтрованной таблице не соответствует вашей основной таблице. Вы также хотите получить ячейку не по indexPath, так как обе таблицы могут значительно отличаться друг от друга по отношению к количеству строк и т.д.

Итак, вместо этого:

UITableViewCell *cell =
[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier
forIndexPath:indexPath];

вместо этого сделайте следующее:

UITableViewCell *cell =
[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];

Ответ 2

Я решил это, дублируя ячейку прототипа в новый xib:

В viewDidLoad:

[self.searchDisplayController.searchResultsTableView registerNib:[UINib nibWithNibName:@"CustomSearchCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"CustomSearchCell"];

И обновленный cellForRowAtIndexPath, чтобы использовать метод tableview не оригинал self.tableview:

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

    [self configureCell:cell atIndexPath:indexPath];
    return cell;
}

Ответ 3

Это старая тема, но если кто-то сталкивается с той же проблемой, для меня это связано с тем, что эта строка в viewDidLoad

self.tableView.estimatedRowHeight = 80;

и в то же время внедрение метода делегата heightForRowAtIndexPath с переменной высотой в разных условиях

if (indexPath.row == 0) {
    return 44 + cellTopSpacing;
} else {
    return 44;
}

Удаление оцененной высоты строки решило ее.

Ответ 4

Если вы используете UISearchDisplayController в методе celForRowAtIndexPath, вы должны использовать метод tableView, а не указатель удержания контроллера.

попробуйте с этим кодом

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