#swift #uitableview
Вопрос:
У меня есть просмотр таблиц, в котором отображаются все новости, затем, если какие-либо новости обновляются или добавляются новые новости, я проверяю и обновляю их следующим образом. Мне интересно, правильный ли мой подход, а также ищу лучшие варианты(tableviewdiffsource?)
В настоящее время пользователь видит следующие 4 новости в таком порядке
[n1, n2, n3, n4]
когда пользователь нажимает на обновление, он получает 3 новости с сервера : [n4, n5, n6]
теперь я должен отображать новости в таком порядке [n4, n5, n6, n1, n2, n3]
var allNews = [News]()
func didFetchNews(newNews:[News]) {
var news:[News] = newNews
var newsSet = Set(newNews)
var deletedPaths = [IndexPath]()
for i in 0..<allNews.count {
let news = allNews[i];
if !newsSet.contains(news) {
news.append(news)
} else {
deletedPaths.append(IndexPath(row: i, section: 0))
}
}
var insertedPath = [IndexPath]()
for i in 0..<newNews.count {
insertedPath.append(IndexPath(row: i, section: 0))
}
self.tableView.beginUpdates()
self.tableView.insertRows(at: insertedPath, with: .automatic)
self.tableView.deleteRows(at: deletedPaths, with: .automatic)
self.tableView.endUpdates()
}
Ответ №1:
DiffableDataSource
вероятно, это самое эффективное решение.
Однако ваш код также может быть оптимизирован с помощью функций более высокого уровня, таких как filter
и map
.
Сначала рассчитываются индексы обновленных новостей. Поскольку новые элементы вставляются сверху, пути индекса вставки равны индексам новых элементов.
Затем элементы удаляются по отфильтрованным индексам, а новые элементы вставляются по индексу 0. reversed()
Позволяет избежать сбоя вне диапазона.
func didFetchNews(newNews: [News]) {
let deletionIndices = allNews.indices.filter{newNews.contains(allNews[$0])}
let deletionIndexPaths = deletionIndices.map{IndexPath(row: $0, section: 0)}
let insertionIndexPaths = newNews.indices.map{IndexPath(row: $0, section: 0)}
for index in deletionIndices.reversed() { allNews.remove(at: index) }
allNews.insert(contentsOf: newNews, at: 0)
self.tableView.beginUpdates()
self.tableView.insertRows(at: insertionIndexPaths, with: .automatic)
self.tableView.deleteRows(at: deletionIndexPaths, with: .automatic)
self.tableView.endUpdates()
}
Комментарии:
1. Большое вам спасибо за этот прекрасный код. Мне интересно , почему мы и тогда, а не сначала и потом .
insertRows
deleteRows
deleteRows
insertRows
self.table.insertRows(at: IndexPaths)
Значит , имеется в видуself.table.deleteRows(at: IndexPaths)
.2. Путем обертывания
insert/delete/move
операторов вbegin-/endUpdates
рамки достаточно умен, чтобы выполнять изменения в правильном порядке.3. порядок
insertRows
иdeleteRows
в томbegin endUpdates
не имеет значения, тогда верно?4. Да, порядок внутри блока не имеет значения.
5. Большое спасибо @vadian