根据来自服务器和本地的数据集更新 TableView
Update TableView based on dataset from server and local
我有一个显示所有新闻的 tableView,如果有任何新闻得到更新或添加了新新闻,我将按如下方式检查和更新。我想知道我的方法是否正确,也在寻找更好的选择(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()
}
DiffableDataSource
可能是最有效的解决方案。
然而,您的代码也可以通过使用更高级别的函数进行优化,例如 filter
和 map
。
首先计算更新新闻的指数。
由于新项目插入到顶部,因此插入索引路径等于新项目的索引。
然后在过滤后的索引处删除项目,并在索引 0 处插入新项目。reversed()
避免了超出范围的崩溃。
func didFetchNews(newNews: [News]) {
let deletionIndices = allNews.indices.filter{newNews.contains(allNews[[=10=]])}
let deletionIndexPaths = deletionIndices.map{IndexPath(row: [=10=], section: 0)}
let insertionIndexPaths = newNews.indices.map{IndexPath(row: [=10=], 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()
}
我有一个显示所有新闻的 tableView,如果有任何新闻得到更新或添加了新新闻,我将按如下方式检查和更新。我想知道我的方法是否正确,也在寻找更好的选择(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()
}
DiffableDataSource
可能是最有效的解决方案。
然而,您的代码也可以通过使用更高级别的函数进行优化,例如 filter
和 map
。
首先计算更新新闻的指数。 由于新项目插入到顶部,因此插入索引路径等于新项目的索引。
然后在过滤后的索引处删除项目,并在索引 0 处插入新项目。reversed()
避免了超出范围的崩溃。
func didFetchNews(newNews: [News]) {
let deletionIndices = allNews.indices.filter{newNews.contains(allNews[[=10=]])}
let deletionIndexPaths = deletionIndices.map{IndexPath(row: [=10=], section: 0)}
let insertionIndexPaths = newNews.indices.map{IndexPath(row: [=10=], 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()
}