有些经验的人可以告诉我在swift避免冻结时从UITableView执行reloadData()的最佳方法是什么?
我有一个带有TableView的ViewController,它显示了一对10行的用户列表。当滚动显示最后一行 - 1,在后台,应用程序请求接下来的10个用户,然后将它们添加到其余用户,以便在TableView中显示20个用户。
当使用委托方法执行此操作时,重新加载会导致大约1~2秒的冻结,并且没有舒适的导航。
有什么想法解决这个问题吗?
答案 0 :(得分:7)
当新数据到来时,您不需要重新加载整个tableView。您只需要相应地插入新行。这不会导致任何滞后/冻结。
func didFinishLoadNewUsers(newUsers: [User]) {
tableView.beginUpdates()
//array of index paths for new rows at the bottom
var indexPaths = [NSIndexPath]()
for row in (currentUsers.count..<(currentUsers.count + newUsers.count)) {
indexPaths.append(NSIndexPath(forRow: row, inSection: 0))
}
//update old data
currentUsers.appendContentsOf(newUsers)
//insert new rows to tableView
tableView.insertRowsAtIndexPaths(indexPaths, withRowAnimation: .Automatic)
tableView.endUpdates()
}
答案 1 :(得分:0)
如果我理解你的问题,你的症状就是:
解决方案:
不要等到最后一行显示出来!例如:当滚动距离底部大约15行的距离时,从40行开始并下载40多行。这样,下载很快就会很快完成,使用户看起来非常流畅。
如果您想获得真正的想象力,可以考虑滚动速度,行高和服务器延迟。但根据我的经验,对于平滑无限的滚动而言,这一切都不是必需的。经验。
在充分尊重的情况下,您和其他响应者认为重新加载整个表视图是错误的。对此负责。 UITableView.reloadData()实际上是无缝的(如果用户尚未到达底部)。
试试这个:
var shouldDownloadMoreRows : Bool {
get {
// This should return false if the server tells us there are no more rows.
// For example, if our last request for 40 got less than 40 rows, then we
// can probably assume there are no more.
// It should also return false if a request is currently in progress, or a
// request failed within the last 0.5 seconds or so, or if the controller
// is quitting (about to animate away).
return ...
}
}
func downloadMoreRows() {
...
// After the download finishes
didFinishDownloadingMoreRows()
}
func didFinishDownloadingMoreRows() {
// This will be smooth. It will not disrupt scrolling or cause any freezing or lag.
self.tableView.reloadData()
}
func tableView(tableView: UITableView,
willDisplayCell cell: UITableViewCell,
forRowAtIndexPath indexPath: NSIndexPath) {
let numRowsInSection = tableView.numberOfRowsInSection(indexPath.section)
if self.shouldDownloadMoreRows && indexPath.row + 15 >= numRowsInSection {
self.downloadMoreRows()
}
}