Сбой с отсутствующей ячейкой для вновь видимой строки при обновлении 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:
Если вы переопределите этот метод, вы должны обязательно вызвать реализацию суперкласса.