Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
405 views
in Technique[技术] by (71.8m points)

ios - UICollectionView: Animate cell size change on selection

What I want to do is change the size of an UICollectionViewCell, and to animate that change, when the cell is selected. I already managed to do that unanimated by marking a cell as selected in collectionView: didSelectItemAtIndexPath: and then calling reloadData on my UICollectionView, displaying the selected cell with a different size.

Nevertheless, this happens all at once, and I have no clue how to get that change in size animated. Any ideas?

I already found Animate uicollectionview cells on selection, but the answer was to unspecific for me and I didn't figure out yet if it could also help me in my case.

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

With the help of Chase Roberts, I now found the solution to my problem. My code basically looks like this:

// Prepare for animation

[self.collectionView.collectionViewLayout invalidateLayout];
UICollectionViewCell *__weak cell = [self.collectionView cellForItemAtIndexPath:indexPath]; // Avoid retain cycles
void (^animateChangeWidth)() = ^()
{
    CGRect frame = cell.frame;
    frame.size = cell.intrinsicContentSize;
    cell.frame = frame;
};

// Animate

[UIView transitionWithView:cellToChangeSize duration:0.1f options: UIViewAnimationOptionCurveLinear animations:animateChangeWidth completion:nil];

For further explanation:

  1. One of the most important step is the invalidateLayout call on the UICollectionView.collectionViewLayout you are using. If you forget it, it is likely to happen that cells will grow over the borders of your collection - that's something you most probably don't want to happen. Also consider that your code should at some point present the new size of your cell to your layout. In my case (I'm using an UICollectionViewFlowLayout), I adjusted the collectionView:layout:sizeForItemAtIndexPath method to reflect the new size of the modified cell. Forgetting that part, nothing will happen to your cell sizes at all if you first call invalidateLayout and then try to animate the change in size.

  2. Most strange (at least to me) but important is that you call invalidateLayout not inside the animation block. If you do so, the animation won't display smooth but glitchy and flickering.

  3. You have to call UIViews transitionWithView:duration:options:animations:completion: method with the cell as argument for transitionWithView, not the whole collection view, because it's the cell you want to get animated, not the entire collection.

  4. I used the intrinsicContentSize method of my cell to return the size I want - in my case, I grow and shrink the width of the cell to either display a button or hide it, depending on the selection state of the cell.

I hope this will help some people. For me it took several hours to figure out how to make that animation work correctly, so I try to free others from that time-consuming burden.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...