【问题标题】:Animate frame and layout change of UICollectionViewUICollectionView 的动画框架和布局变化
【发布时间】:2013-09-12 07:36:53
【问题描述】:

我正在尝试创建一种效果,在更改框架大小的同时更改 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 布局和框架大小?

【问题讨论】:

  • 您有没有找到好的解决方案? performBatchUpdates:withCompletion: 很好,但对组合动画 framecontentOffset 变化没有帮助。我想获得此功能,以便在我的布局和 contentOffset 依赖于缩放的地方平滑地动画缩放反弹。
  • @Benjohn 找到了一个好的解决方案吗?刚刚遇到同样的事情,现有的答案并不理想......
  • @aheze 抱歉,我不知道——它比我现在记得的要远:-/

标签: ios uicollectionview uiviewanimation uicollectionviewlayout


【解决方案1】:

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

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

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

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

【讨论】:

  • 你用什么performBatchUpdates:
  • 在更新期间设置新实例,认真的吗?它最终会使您的应用崩溃。
【解决方案2】:

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

【讨论】:

  • 这很方便,但是同时发生的动画帧变化呢?同样,我认为,contentOffset 的变化?我也需要同时发生。
  • 在我的用例中,我的 flowLayout 在滚动和静态时需要不同。我要做的是:(1)在布局中设置一个标志并使用上面的代码使布局无效; (2nd) scrollToIndexPath 使用默认的 collectionViewMethod 动画; (3) 重置布局标志并再次使用上面的代码将其动画化回原始状态。我无法通过同时为它们制作动画来达到预期的效果,所以我只是将动画排入队列。
  • [self.collectionview.collectionViewLayout invalidateLayout]; 在这里很奇怪,它会导致动画中的错误。
【解决方案3】:

当你更新 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];

【讨论】:

    猜你喜欢
    • 2012-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-23
    • 2016-04-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-31
    相关资源
    最近更新 更多