Resizing a UICollectionView animation cell causes unwanted behavior

I have a UICollectionViewController that uses the standard UICollectionViewFlowLayout to display a single vertical column of cells. I am trying to create an expand / collapse animation on a cell while listening to a cell. For this, I use the following code:

 - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath (NSIndexPath *)indexPath { [self.feedManager setCurrentlySelectedCellIndex:indexPath.item]; [self.collectionView performBatchUpdates:nil completion:nil]; } - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { //Return the size of each cell to draw CGSize cellSize = (CGSize) { .width = 320, .height = [self.feedManager heightForCellAtIndexPath:indexPath] }; return cellSize; } 

The 'selectedCellIndex' property on my control object tells the data models to return the expanded or collapsed size inside the heightForCellAtIndexpath:

 [self.collectionView performBatchUpdates:nil completion:nil]; 

Then, the performBatchUpdates:completiong: method perfectly animates this resize. However! When an animation occurs, an expanding cell may cause a partially visible cell at the bottom of the screen to exit the screen.

If this is the case, and I subsequently destroy this cell, the cell will now be off-screen anchored to its old position without animation, while all other visible cells are waiting as desired. My intuition says that this is the correct behavior, since the cell is turned off when the collapse animation is performed, and it is not included in the animation rendering process. My question becomes, how can I prevent this?

I would prefer that all cells come to life together, regardless of whether they are off-screen or not. Any thoughts?

+42
ios animation uicollectionview flowlayout
Jun 04 '13 at 2:54 on
source share
1 answer

This is a UICollectionViewFlowLayout error, but there is a workaround. The problem is that the attributes returned by initialLayoutAttributesForAppearingItemAtIndexPath: have invalid frames. In particular, they have frames of the final, on the screen, and not on the initial, off screen. You just need to override this method and return the correct frames. The basic redefinition structure will look something like this:

 - (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath { UICollectionViewLayoutAttributes *pose = [super initialLayoutAttributesForAppearingItemAtIndexPath:itemIndexPath]; if (<test for incorrect frame>) { CGRect frame = pose.frame; frame.origin.y = <calculate correct frame>; pose.frame = frame; } return pose; } 

You will be responsible for defining scenarios in which you need to adjust frames, which may include maintaining your own internal state. I did not work out this logic, but I did a rough test and was able to get smooth animation.

Summarizing a bit, I believe that there UICollectionViewFlowLayout so buggy, and there are so many corner cases that you can deal with if you have elements moving and leaving the screen, combined with any inserts, deletions or movements, which was easier for me collapse your own simple layouts. If you are not going to do any insertions, deletions or movements, then overriding the UICollectionViewFlowLayout may well be your best bet.

Let me know if you need more help.

EDIT

If you are interested in looking at the 3rd party layout, I will open the original layout of my VCollectionViewGridLayout table and add an example project showing a smooth expanding cell height. Try running the Expand project . There is also "Sort and Filter" with animated sorting and filtering. Both projects allow you to switch between layout and grid so you can see the improvement.

+27
Jun 18 '13 at 15:30
source share



All Articles