UICollectionView attempts to calculate cell's fitting size regardless of flow layout's estimatedItemSize value
| Originator: | argentumko | ||
| Number: | rdar://26887172 | Date Originated: | 20-Jun-2016 |
| Status: | Duplicate of 26956638 (Closed) | Resolved: | |
| Product: | iOS SDK | Product Version: | iOS 9.3 (13E230); also reproducible on iOS 8.x and iOS 10 seed 1. |
| Classification: | Performance | Reproducible: | Always |
Summary: Using a collection view with UICollectionViewFlowLayout instance configured with default estimatedItemSize property value (zero) results in cell's preferredLayoutAttributesFittingAttributes method still called, which results in a potentially expensive Auto Layout-based computation of fitting size. This behaviour is unexpected since, as per documentation of estimatedItemSize: > The default value of this property is CGSizeZero. Setting it to any other value causes the collection view to query each cell for its actual size using the cell’s preferredLayoutAttributesFittingAttributes: method. which implies that default behaviour (using static or delegate-returned item size) does not include calling that method or performing extra size calculations. Calling preferredLayoutAttributesFittingAttributes method on a cell and then discarding its result incurs a performance overhead, noticeable during scrolling of collection view. Steps to Reproduce: 1. Create a single-view iOS project with a storyboard. 2. Add a collection view controller as an initial scene of the storyboard. 3. Configure the cell in the collection view with an identifier and add, for example, a label aligned to the centre of the cell using constraints. Keep the default size of the cell (50,50). 4. Create a UICollectionViewController subclass and assign it to the collection view in the storyboard. Add a basic implementation of numberOfItemsInSection and cellForItemAtIndexPath methods that would display a thousand cells dequeued from the collection view. Do not configure collection view flow layout properties. 5. Launch the app in Time Profiler, and scroll the collection view for a few seconds. Expected Results: Time profiler results do not include calls to cell's preferredLayoutAttributesFittingAttributes method, so default static item size is used as-is. Performance overhead is not incurred. Cells are laid out correctly and have default size. Actual Results: Time Profiler reports substantial amount of time spent in preferredLayoutAttributesFittingAttributes method and Auto Layout code in its implementation, which results in performance drop. Cells are still laid out correctly and have default size (fitting size is not used to determine cell size). Version: iOS 9.3 (13E230); also reproducible on iOS 8.x and iOS 10 seed 1. Notes: A functioning workaround is to override preferredLayoutAttributesFittingAttributes method in UICollectionViewCell subclass and immediately return supplied layoutAttributes from there, thus circumventing any layout computations and forcing the collection view to just use static or delegate-provided item size. However, having to do so for all cells is not ideal and undocumented. Not all apps use auto sizing in collection views, but many still wish to use Auto Layout in cells to layout their contents based on static or manually calculated dimensions. This issue thus introduces unexpected performance issues for all such apps. Attached sample project demonstrates the issue; please refer to comments and #warnings in its source code for more information. Configuration: Any device or simulator Attachments: 'CollectionViewTest.zip' was successfully uploaded. (https://github.com/vlas-voloshin/CollectionViewAutoSizingBug)
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!
Vlas Voloshin
Please also note that this behaviour has been confirmed as a likely bug by UIKit engineer at WWDC labs.