在UITableView或UICollectionView上加载vs可见单元格

时间:2016-08-25 01:26:43

标签: uitableview uicollectionview uicollectionviewcell ios10

随着iOS 10的推出,似乎我们将拥有prefetching enabled by default on UITableView and UICollectionViews。这意味着屏幕上未显示的单元格将在用户实际看到之前被提取。

以下是一些相关方法:

UITableView

UICollectionView

所有这些都在他们的描述中特别提到“可见”。随着在iOS 10中引入预取,我如何区分预取的单元格与当前可见的单元格?

换句话说:

  1. 如何获得所有可见细胞?
  2. 如何获取所有已加载的单元格?
  3. 看起来UITableView或UICollectionView上没有任何新的API可以帮助解决这个问题。

1 个答案:

答案 0 :(得分:26)

TL; DR

  • 从字面上取得visible函数名称。
  • UITableView的行为与在iOS 9中的行为相同。
  • 如果要在iOS 10上的UICollectionView中以不同方式处理已加载和可见的单元格,则需要进行一些簿记。

UITableView和UICollectionView在预取时的行为看起来非常不同。

首先要注意的是,预取单元和预取数据之间存在差异:

  • 预取单元格是指在单元格实际显示在屏幕上之前调用的cellForRowAtIndexPath。这样可以启用您的单元格处于屏幕外但仍然加载的情况。
  • 预取数据是指prefetchDataSource方法,它们会告知您将要在屏幕上显示的indexPaths。调用此方法时,您没有对单元格的引用,并且在调用此方法时不返回单元格。相反,此方法应该执行诸如触发网络请求以下载将在单元格中显示的图像之类的操作。

注意:在所有这些场景中,假设在任何给定时间都可以显示8个单元格。

UITableView :(选项:no prefetchingprefetch data

  • 永远不会预取单元。换句话说,它永远不会在未显示的cellForRowAtIndexPath上调用indexPath
  • 因此,UITableView上没有isPrefetchingEnabled属性。
  • 您可以使用prefetchDataSource选择预取数据
  • 请注意,虽然表格视图似乎确实是less aggressive with reusing cells,但当重复使用的单元格返回到屏幕时,它仍会显示为cellForItemAtIndexPath。 (虽然我可能需要对此进行更多调查,尤其是对于集合视图。)

UICollectionView :(选项:no prefetchingprefetch cellsprefetch cells and data

  • 默认情况下预取单元格。换句话说,对于不会立即显示的单元格,它会调用cellForItemAtIndexPath
  • 仅当用户在集合视图上向上或向下滚动时才开始预取单元格。换句话说,在加载视图时,您将获得cellForItemAtIndexPath的8次调用。只有当用户向下滚动时,它才会开始询问不可见的单元格(例如,如果向下滚动显示2-10,则可能要求11-14)。
  • 当屏幕上显示预取的不可见单元格时,它不会再次调用cellForItemAtIndexPath。它会假设您第一次执行的实例化仍然有效。
  • 您可以使用prefetchDataSource选择预取数据
  • prefetchDataSource仅对初始加载有用。在上面的相同场景中,当显示前8个单元时,它可以例如触发对单元9-14的数据的预取。但是,一旦调用了这个初始方法,此后就没用了。这是因为在每次调用cellForItemAtIndexPath后会立即调用prefetchItemsAt。例如,您会prefetchItemsAt:[14, 15]紧跟cellForItemAt:14cellForItemAt:15
  • 您可以通过设置isPrefetchingEnabled = false来选择退出所有预取行为。这意味着您不能使UICollectionView的行为与具有prefetchDataSource的UITableView类似。或者,换句话说,您不能只拥有UICollectionView prefetch data

对于两者

  • visibleCellsindexPathsForVisibleRowscellForItemAtIndexPath完全按照他们的说法完成:它们只处理可见单元格。在我们的相同场景中,如果我们加载了20个单元格,但屏幕上只能看到8个单元格。所有这三种方法都只会报告8个屏幕上的细胞。

那是什么意思?

  • 如果您使用的是UITableView,您可以按原样使用它,而不必担心加载单元格与可见单元格之间的差异。它们总是相同的。
  • 另一方面,对于UICollectionView,如果你关心这种差异,你需要做一些记账来跟踪加载的,不可见的细胞和可见细胞。您可以通过查看数据源和委托方法的一些方法(例如willDisplayCell,didEndDisplayingCell)来完成此任务。