Animate frame and layout change of UICollectionView
Solution 1
I don't have a specific answer, but a few suggestions to consider.
UICollectionView
doesn't always handle switching layout instances gracefully. Here is a good discussion of the problem and some workarounds.
But what I’ve actually done in practice that worked for me was to implement both layouts in a single layout object that knows how to toggle between layout modes. I found that switching layout modes in a batch update block was less problematic than using setCollectionViewLayout
with two different layout instances:
[self.collectionView performBatchUpdates:^{
MyLayout *layout = (MyLayout *)self.collectionView.collectionViewLayout;
layout.mode = otherLayoutMode;
} completion:nil];
Solution 2
First set the grid item size like gridItemSize = CGSizeMake(98, 98);
then perform the batch action of UICollectionView. The items in collection view change their sizes with animation. :)
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout*)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return CGSizeMake(gridItemSize.width, gridItemSize.height);
}
[self.collectionview performBatchUpdates:^{
[self.collectionview.collectionViewLayout invalidateLayout];
[self.collectionview setCollectionViewLayout:self.collectionview.collectionViewLayout animated:YES];
} completion:^(BOOL finished) {
}];
Related videos on Youtube
Avba
Updated on December 27, 2020Comments
-
Avba over 3 years
I am trying to create an effect where I change the layout of my UICollectionView while changing the frame size
Initially the collectionView layout presents a "thumbnail" gallery style full screen.
After resizing the frame to a thin strip - I would like to present a "film strip" style layout
both layouts independently work fine and as expected.
I tried code similar to this:
[UIView animateWithDuration:1 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{ self.collectionview.frame = newFrame; // animate the frame size } completion:^(BOOL finished) { [self.collectionView.collectionViewLayout invalidateLayout]; [self.collectionView setCollectionViewLayout:filmstriplayout animated:YES]; // now set the new layout }];
But it is looking very choppy and not resizing as expected.
Is there a way where I could change the collectionview layout and the frame size simultaneously while animating the change?
-
Benjohn almost 9 yearsDid you ever get a good solution?
performBatchUpdates:withCompletion:
is good, but doesn't help with combining an animatedframe
orcontentOffset
change. I want to get this for smoothly animating zoom bounce back where my layout andcontentOffset
dependent on zoom. -
aheze about 3 years@Benjohn did you find a good solution? Just came across the same thing and the existing answers aren't ideal...
-
Benjohn about 3 years@aheze Sorry, I don’t know — it’s further back than I can remember now :-/
-
-
alltom about 10 yearsWhat do you use
performBatchUpdates:
? -
Benjohn almost 9 yearsThis is handy stuff, but what about that animated frame change occurring at the same time? Equivalently, I think, a
contentOffset
change? I also need both to happen at once. -
marcelosalloum over 4 yearsIn my use case, my flowLayout needs to be different when it's being scrolled and when it's static. What I do is: (1st) set a flag in the layout and use the code above to invalidate the layout; (2nd) scrollToIndexPath animated using the default collectionViewMethod; (3rd) reset the layout flag and use the above code again to animate it back to the original state. I couldn't achieve the desired results by animating them at the same time, so I just queued the animations.
-
surfrider about 4 years
[self.collectionview.collectionViewLayout invalidateLayout];
is odd here, it leads to bugs in animation. -
Abdul Yasin over 3 yearsSetting a new instance during an update, seriously?. It will eventually crash your app.