With the introduction of iOS 10, it seems like we're going to have prefetching enabled by default on UITableView and UICollectionViews. This means that cells that aren't displayed on the screen are going to be fetched before the user actually sees them.
Here are some relevant methods:
UITableView:
nil
if the cell is not visible."UICollectionView:
nil
if the cell is not visible."All these specifically mention "visible" in their descriptions. With the introduction of pre-fetching in iOS 10, how would I distinguish between a cell that was pre-fetched vs. one that is currently visible?
In other words:
It does not look like there are any new APIs on either UITableView or UICollectionView that can help with this.
TL;DR
visible
in function names literally. UITableView and UICollectionView appear to behave very differently when it comes to prefetching.
First thing to notice is that there is a difference between prefetching cells and prefetching data:
cellForRowAtIndexPath
being called before the cell is actually displayed on screen. This enables the scenario where you have cells that are off-screen but still loaded.prefetchDataSource
methods which inform you about indexPaths
that are going to be displayed on screen. You do not have a reference to the cell when this method is called, and you do not return a cell when this method is called. Instead, this method should do things like fire off a network request to download an image that will be displayed in the cell.Note: In all of these scenarios, imagine there are 8 cells that can be displayed at any given time.
UITableView: (options: no prefetching
, or prefetch data
)
cellForRowAtIndexPath
on an indexPath
that isn't displayed.isPrefetchingEnabled
property on a UITableView.prefetchDataSource
.cellForItemAtIndexPath
when the reused cell comes back on screen. (Although I may need to do some more investigation as to this, especially for collection views.)UICollectionView: (options: no prefetching
, prefetch cells
, or prefetch cells and data
)
cellForItemAtIndexPath
for cells that aren't going to be immediately displayed.cellForItemAtIndexPath
when the view is loaded. Only once the user scrolls down will it start asking for non-visible cells (e.g. if you scrolled down to show 2-10, it might ask for 11-14).cellForItemAtIndexPath
again. It's going to assume that instantiation you did the first time is still valid.prefetchDataSource
.prefetchDataSource
turns out to be only useful for the initial load. In the same scenario above, when the first 8 cells are displayed, it may fire off a prefetching of data for cells 9-14, for example. However, once this initial method is called, it's useless thereafter. This is because cellForItemAtIndexPath
is going to be called immediately after each call to prefetchItemsAt
. For example, you'll get prefetchItemsAt:[14, 15]
immediately followed by cellForItemAt:14
, cellForItemAt:15
.isPrefetchingEnabled = false
. This means you can't make a UICollectionView behave similarly to a UITableView with a prefetchDataSource
. Or, in other words, you can not have a UICollectionView prefetch data
only.For both:
visibleCells
, indexPathsForVisibleRows
, and cellForItemAtIndexPath
do exactly as they say: they only deal with visible cells. In our same scenario, if we have 20 cells loaded, but only 8 are visible on screen. All 3 of these methods will only report about the 8 on-screen cells.So what does this mean?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With