AtelierClockwork

Lessons in Collection View Layouts

I spent several days nailing down an animated collection view transition this week. The layout was already working reliably in a static format, but getting the collection to animate cell removal and addition was something that we wanted to do.

One of several complicating factors was that the cells overlap, and each item is slightly scaled down, then offset vertically to make a “card stack” appearance. The complications also include gesture recognizers, and the fact that I used a collection view layout that aggregated a series of sub-layouts to allow for mixing the card stack, a table view like layout, and a horizontal flow layout into one collection view. Those ended up only marginally increasing the complexity of the problem I was actually trying to solve.

My first approach was creating a new frame for the [UICollectionViewLayoutAttributes](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UICollectionViewLayoutAttributes_class/#//apple_ref/occ/instp/UICollectionViewLayoutAttributes/frame) sent by [initialLayoutAttributesForAppearingItemAtIndexPath](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UICollectionViewLayout_class/index.html#//apple_ref/occ/instm/UICollectionViewLayout/initialLayoutAttributesForAppearingItemAtIndexPath:) in the appropriate UICollectionViewLayout. This got me about 90% of the way there, but the animation appeared to be pulling in from down and to the right.

After removing anything that may have caused layout issues, and stepping through my math in the debugger, I set the simulator to slow animations and scrutinized the issue and realized that the problem was that the origin was animating correctly, but the cell was starting the animation at full size. I finally fixed the problem by calculating the appropriate transform value on for the primary layout attributes, and that animated smoothly. In retrospect this is probably implemented to having to re-calculate the interior layout of the cell throughout the transition, but nothing in the documentation made it obvious that using frame wouldn’t properly animate during a transition.