1

I am trying to display a UICollectionView capable of displaying a user's photo library where the photo aspect ratio is respected (constrained by the width of the device - think the instagram full width feed view).

I have used examples from UICollectionView Self Sizing Cells with Auto Layout and https://medium.com/@wasinwiwongsak/uicollectionview-with-autosizing-cell-using-autolayout-in-ios-9-10-84ab5cdf35a2 (there is a PR in the repo linked in the article to update the project for iOS 12 FYI) to setup a UICollectionView with variable height cells, but all of these are super laggy/terrible to use when there are a large amount of cells in the view.

For example, the sample app (with iOS 12 fix) here: https://github.com/tttsunny/CollectionViewAutoSizingTest/pull/5 works great with 100 cells, but if you try to display 30,000 then the app is unusable - it gets stuck scrolling and is not responsive. The latency is in the estimated size logic of the UIViewController.

Is using an estimated size not recommended for large size UICollectionView objects? What can I do to get the cells to have different height values then?

Zach
  • 3,261
  • 5
  • 18
  • 42

1 Answers1

0

While I can't speak to all large collection views, if you are seeing all your latency in the estimated size calculation, then sizing your cells a different way is likely to help a lot. Since you have a fixed width in this scenario, and simply need to calculate the height for each cell, you can accomplish all your size calculations off the main thread, which'll hopefully stop your scrolling getting suck and unresponsive.

More practically, for each "page" of images (I'd recommend starting with 20, but you can adjust this based on how it works in your situation), calculate the required cell heights for each. Do this in a background queue, by looking at the UIImage imageSize, and getting your cell height with: (imageSize.height / imageSize.width) * UIScreen.main.bounds.size.width. You'll need to keep these in memory, probably best alongside the images themselves, and then your sizeForItemAtIndexPath method can just index into that data structure for the cell's size. Then as your user scrolls, calculate the sizes for the "next page" before they get there (using either the collectionView prefetching API or simply hooking into the UIScrollView delegates.

You could even do this calculation in sizeForItemAtIndexPath directly, but calculating things in the background would be even more efficient. Calculating directly in this method could be an easier first step, though :).

BHendricks
  • 4,181
  • 5
  • 28
  • 56