Getting loaded vs visible cells on a UITableView or UICollectionView

Senseful

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:

UICollectionView:

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:

  1. How do I get all visible cells?
  2. How do I get all loaded cells?

It does not look like there are any new APIs on either UITableView or UICollectionView that can help with this.

Senseful

TL;DR

  • Take the visible in function names literally.
  • UITableView behaves just as it did in iOS 9.
  • You'll need to do some bookkeeping if you want to treat loaded vs. visible cells differently in UICollectionView on iOS 10.

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:

  • Prefetching cells refers to the 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.
  • Prefetching data refers to the 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)

  • Does not prefetch cells, ever. In other words, it will never call cellForRowAtIndexPath on an indexPath that isn't displayed.
  • As such, there is no isPrefetchingEnabled property on a UITableView.
  • You can opt-in to prefetching data by using the prefetchDataSource.
  • Note that although the table view does seem to be less aggressive with reusing cells, it still appears to call 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)

  • Prefetches cells by default. In other words, it will call cellForItemAtIndexPath for cells that aren't going to be immediately displayed.
  • The prefetching of cells only begins when the user scrolls up or down on the collection view. In other words, you will get exactly 8 calls to 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).
  • When the prefetched, non-visible cell comes on screen, it's not going to call cellForItemAtIndexPath again. It's going to assume that instantiation you did the first time is still valid.
  • You can opt-in to prefetching data by using the prefetchDataSource.
  • The 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.
  • You can opt-out of all prefetching behavior by setting 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're using a UITableView, you can use it as is and never have to worry about a difference between loaded vs. visible cells. They are always equivalent.
  • For UICollectionView, on the other hand, you're gonna need to do some book-keeping to keep track of loaded, non-visible cells vs. visible cells if you care about this difference. You can do this by looking at some of the methods on the data source and delegate methods (e.g. willDisplayCell, didEndDisplayingCell).

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

How to detect all visible cells of UICollectionView have loaded

From Dev

Update not visible cells in UICollectionView

From Dev

Number of visible cells in UITableView

From Dev

Number of visible cells in UITableView

From Dev

Load only visible cells in UITableView

From Dev

UICollectionView cells with Images inside UITableView prototype

From Dev

UITableView.visibleCells not capturing all visible cells

From Dev

Load Contents based on visible cells in UITableView ios

From Dev

UICollectionView Not Showing Cells Completely. Last Cells Are Not Getting Shown Completely

From Dev

UICollectionView Not Showing Cells Completely. Last Cells Are Not Getting Shown Completely

From Dev

Selecting all the items in UICollectionView iOS, even the cells that are not visible

From Dev

Animating UICollectionView contentOffset does not display non-visible cells

From Dev

UICollectionView - Cells about to be removed are not animated if not visible before update

From Dev

getting data from each UITableView Cells Swift

From Dev

UITableView cells getting corrupted upon scrolling

From Dev

"No rows found" when there's no are row /cells for UICollectionView and UITableView

From Dev

"No rows found" when there's no are row /cells for UICollectionView and UITableView

From Dev

Swift 2.0, UITableView: cellForRowAtIndexPath returning nil for non-visible cells

From Dev

Not loaded uicollectionview?

From Dev

Additional View getting inserted into UICollectionView loaded from Xib

From Dev

UICollectionview and cells

From Dev

Visible lag while scrolling two way scrolling UICollectionView with large number of cells (250,000 or more)

From Dev

Visible lag while scrolling two way scrolling UICollectionView with large number of cells (250,000 or more)

From Dev

How to access and iterate through contentView.subviews in UITableView when cells are not visible?

From Java

Left Align Cells in UICollectionView

From Dev

UICollectionView - Not displaying cells

From Dev

Deleting selected cells in uicollectionview

From Dev

In a UICollectionView, the cells will not sit on the bottom

From Dev

UICollectionView number of cells in the section

Related Related

  1. 1

    How to detect all visible cells of UICollectionView have loaded

  2. 2

    Update not visible cells in UICollectionView

  3. 3

    Number of visible cells in UITableView

  4. 4

    Number of visible cells in UITableView

  5. 5

    Load only visible cells in UITableView

  6. 6

    UICollectionView cells with Images inside UITableView prototype

  7. 7

    UITableView.visibleCells not capturing all visible cells

  8. 8

    Load Contents based on visible cells in UITableView ios

  9. 9

    UICollectionView Not Showing Cells Completely. Last Cells Are Not Getting Shown Completely

  10. 10

    UICollectionView Not Showing Cells Completely. Last Cells Are Not Getting Shown Completely

  11. 11

    Selecting all the items in UICollectionView iOS, even the cells that are not visible

  12. 12

    Animating UICollectionView contentOffset does not display non-visible cells

  13. 13

    UICollectionView - Cells about to be removed are not animated if not visible before update

  14. 14

    getting data from each UITableView Cells Swift

  15. 15

    UITableView cells getting corrupted upon scrolling

  16. 16

    "No rows found" when there's no are row /cells for UICollectionView and UITableView

  17. 17

    "No rows found" when there's no are row /cells for UICollectionView and UITableView

  18. 18

    Swift 2.0, UITableView: cellForRowAtIndexPath returning nil for non-visible cells

  19. 19

    Not loaded uicollectionview?

  20. 20

    Additional View getting inserted into UICollectionView loaded from Xib

  21. 21

    UICollectionview and cells

  22. 22

    Visible lag while scrolling two way scrolling UICollectionView with large number of cells (250,000 or more)

  23. 23

    Visible lag while scrolling two way scrolling UICollectionView with large number of cells (250,000 or more)

  24. 24

    How to access and iterate through contentView.subviews in UITableView when cells are not visible?

  25. 25

    Left Align Cells in UICollectionView

  26. 26

    UICollectionView - Not displaying cells

  27. 27

    Deleting selected cells in uicollectionview

  28. 28

    In a UICollectionView, the cells will not sit on the bottom

  29. 29

    UICollectionView number of cells in the section

HotTag

Archive