As the user types, I am retrieving results (text) by traversing a local word graph in a background thread. Each keystroke cancels the previous operation. If the operation completes, the data source is updated and reloadData is called on the main thread. This works great and is very fast (as fast as the user can type), even when tens of thousands of results are returned.
To customize the size of each collection view cell, I implemented sizeForItemAtIndexPath for the UICollectionViewDelegateFlowLayout delegate. Unfortunately, this results in a small, but noticeable lag when the user types. To be sure the time was not lost in my size calculation logic, I tried just returning a fixed size, but it still killed performance. I am surprised at this because there are only ~120 cells or so on the screen at any given time. When commenting out this method, the response time is again immediate, even for very large data sets.
Any ideas for improving the performance of UICollectionView with custom cell sizes?
Thanks
Additional clarification...
The program returns all possible words from the given set of letters then sorts by score or alphabetically, etc. As the user types, the total word count goes up fast (exponentially, if multiple wildcards are entered). The words change as you type so the width of the cells update accordingly and wrap to the next line as handled by the flow layout.
The issue seems to be the number of cells shown on the screen at any given time. In sizeForItemAtIndexPath, if I just return a large size where only one or two cells are visible, the update is very fast; however, if I return a size that just fits the text, I end up with 100+ visible cells and there is a lag. If I comment out sizeForItemAtIndexPath and just use a fixed size cell, it is fast, but that is not what I am going for.
class MyLayout: UICollectionViewFlowLayout { override func prepare() { super. prepare() guard let collectionView = collectionView else { return } itemSize = CGSize(width: ..., height: ...) } }
A layout object that organizes items into a grid with optional header and footer views for each section.
You don't need to reload UICollectionView
by calling reloadData
, instead you can use:
[self.collectionView reloadItemsAtIndexPaths:[NSArray arrayWithObject:indexPath]];
Here, indexPath
is the NSIndexPath
object for the corresponding UICollectionViewCell
object
that you want to update.
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