ios UICollectionView 的动画框架和布局变化

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18687648/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 01:02:04  来源:igfitidea点击:

Animate frame and layout change of UICollectionView

iosuicollectionviewuiviewanimationuicollectionviewlayout

提问by Avner Barr

I am trying to create an effect where I change the layout of my UICollectionView while changing the frame size

我正在尝试创建一种效果,在更改框架大小的同时更改 UICollectionView 的布局

Initially the collectionView layout presents a "thumbnail" gallery style full screen.

最初 collectionView 布局呈现一个“缩略图”画廊风格的全屏。

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?

有没有一种方法可以在为更改设置动画的同时同时更改 collectionview 布局和框架大小?

回答by Timothy Moose

I don't have a specific answer, but a few suggestions to consider.

我没有具体的答案,但有一些建议需要考虑。

UICollectionViewdoesn't always handle switching layout instances gracefully. Here is a good discussion of the problem and some workarounds.

UICollectionView并不总是优雅地处理切换布局实例。这是对问题和一些解决方法的很好的讨论

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 setCollectionViewLayoutwith two different layout instances:

但是我实际上在实践中所做的对我有用的是在一个知道如何在布局模式之间切换的单个布局对象中实现两种布局。我发现在批量更新块中切换布局模式比使用setCollectionViewLayout两个不同的布局实例问题要少:

[self.collectionView performBatchUpdates:^{
    MyLayout *layout = (MyLayout *)self.collectionView.collectionViewLayout;
    layout.mode = otherLayoutMode;
} completion:nil];

回答by Zulqarnain

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. :)

首先设置网格项大小,gridItemSize = CGSizeMake(98, 98);然后执行 UICollectionView 的批处理操作。集合视图中的项目通过动画改变它们的大小。:)

- (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) {    
}];

回答by Shivam Singh

Here is the simple trick whenever you are updating the CollectionView use this:

每当您更新 CollectionView 时,这是一个简单的技巧:

[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];