Reputation: 15266
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?
Upvotes: 21
Views: 32706
Reputation: 9915
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];
Upvotes: 21
Reputation: 83
Here is the simple trick whenever you are updating the CollectionView use this:
[self.collectionView removeFromSuperview]; //First remove the Collection View
//Relocate the view with layouts
UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init];
layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
layout.minimumInteritemSpacing = 10;
layout.minimumLineSpacing = 10;
self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.width,100) collectionViewLayout:layout];
[self.collectionView setDataSource:self];
[self.collectionView setDelegate:self];
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cellIdentifier"];
[self.collectionView reloadData];
[self.view addSubview:self.collectionView];
Upvotes: -3
Reputation: 1653
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) {
}];
Upvotes: 20