动画UICollectionView的框架和布局更改

时间:2013-09-08 19:18:31

标签: ios uicollectionview uiviewanimation uicollectionviewlayout

我正在尝试创建一个效果,我在更改帧大小的同时更改了UICollectionView的布局

最初,collectionView布局全屏显示“缩略图”库样式。

将框架尺寸调整为细条后 - 我想呈现一个“电影条”风格的布局

这两种布局都可以正常工作并且符合预期。

我尝试过类似的代码:

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

但它看起来非常不稳定,没有按预期调整大小。

有没有办法在动画更改的同时更改collectionview布局和帧大小?

4 个答案:

答案 0 :(得分:19)

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

UICollectionView并不总是优雅地处理切换布局实例。这是一个很好的discussion of the problem and some workarounds

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

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

答案 1 :(得分:16)

首先将网格项大小设置为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) {    
}];

答案 2 :(得分:0)

我在动画块中调用UICollectionViewLayout的自定义layoutIfNeeded上设置了大小变化,因为performBatchUpdates似乎无效。添加setCollectionViewLayout似乎也没什么作用

UIView.animate(withDuration: 0.2, animations: {
  let layout = self.collectionView.collectionViewLayout as! CustomFlowLayout
  self.collectionView.collectionViewLayout.invalidateLayout()

  let size = smallCollection
    ? CGSize(width: 44, height: 44)
    : CGSize(width: 120, height: 120)

  layout.size = size
  self.collectionView.layoutIfNeeded()
})

答案 3 :(得分:-2)

无论何时更新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];