如何重新加载UITableView数据,避免冻结

时间:2016-08-03 16:04:38

标签: ios swift uitableview

有些经验的人可以告诉我在swift避免冻结时从UITableView执行reloadData()的最佳方法是什么?

我有一个带有TableView的ViewController,它显示了一对10行的用户列表。当滚动显示最后一行 - 1,在后台,应用程序请求接下来的10个用户,然后将它们添加到其余用户,以便在TableView中显示20个用户。

当使用委托方法执行此操作时,重新加载会导致大约1~2秒的冻结,并且没有舒适的导航。

有什么想法解决这个问题吗?

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)

如果我理解你的问题,你的症状就是:

  1. 用户滚动到底部。
  2. 停止滚动(因为已达到底部)。
  3. 您的控制器会注意到用户已到达底部并开始下载更多行。
  4. 新行完成下载时有一个难看的延迟。
  5. 您插入新行,现在用户可以继续滚动。
  6. 用户现在对您的应用感到失望,因为它停止滚动并且没有明显原因延迟。我相信这就是你所说的&#34;冷冻&#34;和#34;不舒服的导航&#34;。
  7. 解决方案:

    不要等到最后一行显示出来!例如:当滚动距离底部大约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()
        }
    }