Чтобы убрать проблему с прыжками, вам нужно установить estimatedHeightForRowAt
такой же, как ваша высота строки.Предполагая, что у вас не будет проблем с производительностью, вы можете просто сделать следующее:
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return self.tableView(tableView, heightForRowAt: indexPath)
}
Или, если высота ячейки постоянна, вы можете сделать tableView.estimatedRowHeight = 70.0
.
Почему это происходит потому, что представление таблицыпри перезагрузке будет использоваться estimatedRowHeight
для ячеек, которые невидимы, что приводит к прыжкам, когда расчетная высота отличается от фактической.Чтобы дать вам представление:
Допустим, предполагаемая высота равна 50
, а реальная высота 75
.Теперь, когда вы прокрутили вниз до 10 ячеек за пределами экрана, у вас есть 10*75 = 750
пикселей смещения контента.Нет, когда происходит перезагрузка, табличное представление будет игнорировать, сколько ячеек скрыто, и попытается пересчитать это.Он будет повторно использовать приблизительную высоту строки, пока не найдет путь индекса, который должен быть видимым.В этом примере он начинает вызывать ваш estimatedHeightForRow
с индексами [0, 1, 2...
и увеличивать offset
на 50
, пока не достигнет смещения вашего контента, которое все еще равно 750
.Так что это означает, что он попадает в индекс 750/50 = 15
.И это приводит к прыжку из ячейки 10
в ячейку 15
при перезагрузке.
Что касается мерцания, существует много возможностей.Вы можете избежать перезагрузки ячеек, которые не нуждаются в перезагрузке, перезагрузив только часть источника данных, которая изменилась.В вашем случае это означает вставку новых строк, таких как:
tableView.beginUpdates()
tableView.insertRows(at: myPaths, with: .none)
tableView.endUpdates()
Все же кажется странным, что вы даже видите мерцание.Если только изображение мерцает, то проблема может быть в другом месте.Получение такого изображения, как правило, является асинхронной операцией, даже если изображение уже кэшировано.Вы можете избежать этого, проверив, действительно ли вам нужно обновить ресурс.Если ваша ячейка уже отображает изображение, которое вы пытаетесь показать, то нет смысла применять новый ресурс:
if let url = BrandsManager.brandLogoURL(forLogoName: brand.logo!) {
if url != cell.currentLeftImageURL { // Check if new image needs to be applied
let resource = ImageResource(downloadURL: url, cacheKey: url.absoluteString)
cell.currentLeftImageURL = url // Save the new URL
cell.leftImageView.kf.setImage(with: resource)
}
} else {
print("Cannot form url for brand logo")
}
Я бы предпочел поместить этот код в саму ячейку, хотя
var leftImageURL: URL {
didSet {
if(oldValue != leftImageURL) {
let resource = ImageResource(downloadURL: url, cacheKey: url.absoluteString)
leftImageView.kf.setImage(with: resource)
}
}
}
но это полностью зависит от вас.