Сбой с отсутствующей ячейкой для вновь видимой строки при обновлении UITableView

У меня возникает сбой при удалении строки.

// Updating my data model 
....
// apply the updates
self.tableView.beginUpdates()
self.tableView.deleteRows(at: indexPathsToDelete, with: .automatic)
self.tableView.endUpdates()

Шаги по воспроизведению - Добавить строки - Удалите строки, в частности, убедитесь, что есть некоторые строки за пределами текущего экрана (который будет отображаться на экране при успешном удалении - Повторяйте до появления сбоя

Это не всегда происходит, поэтому я думаю, что это произойдет только тогда, когда ячейки, которые он пытается загрузить, будут переработаны

Это в симуляторе 10.0 с Xcode 8.0

  *** Assertion failure in -[UITableView _updateWithItems:updateSupport:],
 /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3599.6/UITableView.m:3149
 Missing cell for newly visible row 2
 (null)

для cellForRowAt

if isMultipe{
   let cell =  tableView.dequeueReusableCell(withIdentifier: DetailsTableViewCell.defaultIdentifier, for: indexPath) as! DetailsTableViewCell
return cell
    } else {
let cell =  tableView.dequeueReusableCell(withIdentifier: DetailsMultipleTableViewCell.defaultIdentifier, for: indexPath) as! DetailsMultipleTableViewCell
   return cell
}

указанная здесь ошибка: https://forums.developer.apple.com/thread/49676

Ответы

Ответ 1

У меня была такая же проблема, и я обнаружил, что UITableView имеет серьезные проблемы с анимацией строк вставки/обновления/удаления, когда заголовки разделов являются переменной высотой. Просто преобразуйте высоту в константу и повторите попытку.

Это фактически означает удаление estimatedSectionHeaderHeight.

Ответ 2

В моем случае это сбой, когда ячейки использовали автозапуск для вычисления его высоты. Таким образом, единственным гарантированным решением является использование ручных вычислений высот. (что на самом деле грустно..)

Ответ 3

В моем случае у меня была эта проблема только для вставки первой строки в пустой раздел, поэтому я попытался ее исправить следующим образом:

self.array.append(item)
if self.array.count > 1 {
    self.tableView.beginUpdates()
    self.tableView.insertRows(at: indexPathes, with: .top)
    self.tableView.endUpdates()
} else {
    self.tableView.reloadSections([1], with: .fade)
}

Ответ 4

Эта проблема случилась со мной, когда у меня были клетки разных размеров. Мой код:

tableView.estimatedRowHeight = 150
tableView.rowHeight = UITableViewAutomaticDimension

Во время перемещения/вставки/удаления приложение вылетало с сообщением "Missing cell for newly visible row". Итак, я удалил эту строку:

tableView.estimatedRowHeight = 150

и реализовать метод делегата, в котором возвращается отдельная оценочная высота для каждой строки.

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {}

Надеюсь, это кому-нибудь поможет.

Ответ 5

Удалить indexPath в tableView.dequeueReusableCell

if isMultipe{
   let cell =  tableView.dequeueReusableCell(withIdentifier: DetailsTableViewCell.defaultIdentifier) as! DetailsTableViewCell
return cell
    } else {
let cell =  tableView.dequeueReusableCell(withIdentifier: DetailsMultipleTableViewCell.defaultIdentifier) as! DetailsMultipleTableViewCell
   return cell
}

Ответ 6

У меня была аналогичная проблема.

emrekyv предложил удалить estimatedSectionHeaderHeight, но у меня есть таблица с одним сеансом, без заголовка и без нижнего колонтитула.

Расширение его идеи и установка estimatedRowHeight на 0 (= не автоматическая) устранили проблему.

Итак, это правило:

Не оценивайте высоту при обновлении UITableView.

Ответ 7

В моем случае это произошло, когда я забыл вызвать super.prepareForReuse() в моем собственном подклассе.

См. Https://developer.apple.com/documentation/uikit/uitableviewcell/1623223-prepareforreuse:

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