Это, к сожалению, не такая простая задача, как можно подумать. Таблица добавляется при добавлении ячейки сверху, поскольку смещение сохраняется и ячейки обновляются. Таким образом, в некотором смысле, это не табличное представление, которое прыгает, ячейки прыгают, так как вы добавили новый сверху, что имеет смысл. То, что вы хотите сделать, это чтобы ваш табличный вид перепрыгивал с добавленной ячейкой.
Я надеюсь, что вы установили фиксированную или вычисленную высоту строки, потому что с автоматическими размерами вещи могут немного усложниться. Важно иметь ту же расчетную высоту, что и фактическая высота для ряда. В моем случае я просто использовал:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 72.0
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 72.0
}
Затем для целей тестирования я добавляю новую ячейку сверху при нажатии любой из ячеек:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
var offset = tableView.contentOffset.y
cellCount += 1
tableView.reloadData()
let paths = [IndexPath(row: 0, section: 0)]
paths.forEach { path in
offset += self.tableView(tableView, heightForRowAt: path)
}
DispatchQueue.main.async {
tableView.setContentOffset(CGPoint(x: 0.0, y: offset), animated: false)
}
}
Поэтому я сохраняю текущее смещение табличного представления. Затем я изменяю источник данных (мой источник данных просто показывает количество ячеек). Затем просто перезагрузите представление таблицы.
Я беру все пути индекса, которые были добавлены, и изменяю смещение, добавляя ожидаемую высоту каждой добавленной ячейки.
В конце я применяю новое смещение контента. И важно сделать это в следующем цикле выполнения, что легко сделать, отправив его асинхронно в основную очередь.
Что касается автоматических размеров.
Я бы не пошел туда, но важно иметь размер кэша.
private var sizeCache: [IndexPath: CGFloat] = [IndexPath: CGFloat]()
Затем вам нужно заполнить кеш размера, когда ячейка исчезнет:
func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
sizeCache[indexPath] = cell.frame.size.height
}
и изменить расчетную высоту:
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return sizeCache[indexPath] ?? 50.0
}
Также при изменении смещения вам нужно использовать приблизительную высоту:
paths.forEach { path in
offset += self.tableView(tableView, estimatedHeightForRowAt: path)
}
Это сработало для моего случая, но автоматические размеры иногда сложны, поэтому удачи с ними.