返回

如何在 cell 上正确地更新进度条?

IOS

如何正确地更新cell上的进度条? #

从Swift 3.0开始,苹果为我们引入了 UITableViewDataSourcePrefetching 协议,这个协议用于预取数据。为什么要进行数据预取呢?想想我们平时做的一些操作:

  • 在表格最下面创建了一个新的 cell。
  • 滚动 UITableView。
  • 刷新一个已经存在的 cell。

数据预取是在这些情况发生的时候发生预取行为,因为在这种情况下,UI 主线程可能会有比较重的任务,比如创建/绑定 cell。因此在这种场景下,UI 主线程并不适合于进行计算密集型的任务。这就是为什么苹果提供 UITableViewDataSourcePrefetching 协议,以便让开发者可以将这些计算密集型的任务转移到后台线程。

不过,这个协议和进度条并没有什么关系啊,它和进度条有什么关联呢?其实,如果你在滚动 UITableView 的时候,观察 cell 中进度条的变化,你可能会发现,进度条不会随着滚动而一直流畅地变化,会出现顿挫的情况。为什么会这样呢?

原因就在于预取数据发生的时候,系统可能会回调 cell 中的进度条的 progress 方法来更新进度条。而 progress 方法执行的线程是主线程。而在预取数据发生的时候,我们的主线程其实很忙,它正在进行创建/绑定 cell 的操作。所以,当 progress 方法被回调的时候,它可能会因为主线程任务繁忙而被延迟,这样进度条的更新就会出现卡顿。

因此,如果你想要流畅地更新 cell 中的进度条,你不能在 progress 方法中更新进度条。你应该将进度条的更新操作放在预取方法中。因为在预取方法中,系统会提前预取数据,这样可以保证主线程在更新进度条的时候不会那么繁忙,进度条就可以流畅地更新了。

所以,如果你想在 cell 中更新进度条,可以使用 UITableViewDataSourcePrefetching 协议的 prefetchRows(at:) 方法来更新进度条。

以下是使用 UITableViewDataSourcePrefetching 协议更新 cell 中进度条的步骤:

  1. 在你的 cell 中定义一个进度条。
  2. 在你的 ViewController 中,实现 UITableViewDataSourcePrefetching 协议的 prefetchRows(at:) 方法。
  3. 在 prefetchRows(at:) 方法中,获取要预取的行号数组。
  4. 遍历行号数组,并为每一行更新进度条。

这样,你就可以流畅地更新 cell 中的进度条了。

我希望这篇文章对你有帮助。如果你有任何其他问题,请随时问我。