UICollectionView Frustrations
09/09/15 12:48 PM
It feels like a disproportional amount of my time is spent trying to bend UICollectionView to my will. The challenge this time was to have the collection view use self-sizing cell (a simple one with just a label), with a minimum size. I went through many Stack Overflow posts, watched Session 226 of WWDC again (“Just one line of code - there is no step two! - ARGH!), and finally came up with a solution that worked for me.
The bug I was running into is that I could set a estimated cell size of the content view, and it mostly used that estimated size. However, some cells that are loaded later in the collection (not visible on screen immediately), have a wider width. That’s fine - they get wider. However, when I scroll back up to the top of the UICollectionView, some of the previously smaller cells now had a wider width. If I kept scrolling back and forth, the wider cells would slowly infect the smaller ones, and even the smaller ones would start showing up in the wider cells.
No combination of constraints that I could find would solve the problem. Reseting the bounds of the cell in prepareForReuse() didn’t work. I eventually ended up overriding preferredLayoutAttributesFittingAttributes on my UICollectionViewCell subclass. In that method, I determine the length of the text label (by calling sizeToFit on the label), and then rounding up with width and height to 50 if needed. Otherwise, I add in 8 pixels of padding on either end and return that size. Voila! Correctly sized cells, with no regressions as you scroll around.
I have no idea if this is performant, or even a good idea. This isn’t a performance-critical collection view, and the number of cells it displayed is fixed, so I’m just happy it’s working.
Someday UICollectionView….. you and I are going to have a serious chat.
The bug I was running into is that I could set a estimated cell size of the content view, and it mostly used that estimated size. However, some cells that are loaded later in the collection (not visible on screen immediately), have a wider width. That’s fine - they get wider. However, when I scroll back up to the top of the UICollectionView, some of the previously smaller cells now had a wider width. If I kept scrolling back and forth, the wider cells would slowly infect the smaller ones, and even the smaller ones would start showing up in the wider cells.
No combination of constraints that I could find would solve the problem. Reseting the bounds of the cell in prepareForReuse() didn’t work. I eventually ended up overriding preferredLayoutAttributesFittingAttributes on my UICollectionViewCell subclass. In that method, I determine the length of the text label (by calling sizeToFit on the label), and then rounding up with width and height to 50 if needed. Otherwise, I add in 8 pixels of padding on either end and return that size. Voila! Correctly sized cells, with no regressions as you scroll around.
I have no idea if this is performant, or even a good idea. This isn’t a performance-critical collection view, and the number of cells it displayed is fixed, so I’m just happy it’s working.
Someday UICollectionView….. you and I are going to have a serious chat.