ios - UICollectionView 动画单元格大小更改会导致不良行为

标签 ios animation uicollectionview flowlayout

我有一个 UICollectionViewController,它使用标准 UICollectionViewFlowLayout 来显示单个垂直单元格列。我正在尝试在点击单元格时在单元格上创建展开/折叠动画。我使用以下代码来完成此操作:

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath (NSIndexPath *)indexPath
{
    [self.feedManager setCurrentlySelectedCellIndex:indexPath.item];
    [self.collectionView performBatchUpdates:nil completion:nil];
}

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
    //Return the size of each cell to draw
    CGSize cellSize = (CGSize) { .width = 320, .height = [self.feedManager heightForCellAtIndexPath:indexPath] };
    return cellSize;
}

我的管理对象上的“selectedCellIndex”属性告诉数据模型在 heightForCellAtIndexpath 中返回展开或折叠的大小:

[self.collectionView performBatchUpdates:nil completion:nil];

然后 performBatchUpdates:completiong: 方法很好地动画了这个大小变化。然而!当动画发生时,展开的单元格可能会导致屏幕底部的部分可见单元格离开屏幕。

如果是这种情况并且我随后折叠了这个单元格,现在离开屏幕的单元格将捕捉到它的旧位置而没有动画,而所有其他可见单元格将根据需要设置动画。我的直觉告诉我这是正确的行为,因为当执行折叠动画时单元格不在屏幕上,并且不包含在动画渲染过程中。我的问题是,如何防止这种情况发生?

我希望所有单元格都一起动画,无论它们是否在屏幕外。有什么想法吗?

最佳答案

这是一个 UICollectionViewFlowLayout 错误,但有一个解决方法。问题是 initialLayoutAttributesForAppearingItemAtIndexPath: 返回的属性有错误的帧。具体来说,它们具有最终屏幕上位置的帧,而不是初始屏幕外位置的帧。您只需要覆盖此方法并返回正确的帧。覆盖的基本结构如下所示:

- (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath
{
    UICollectionViewLayoutAttributes *pose = [super initialLayoutAttributesForAppearingItemAtIndexPath:itemIndexPath];
    if (<test for incorrect frame>) {
        CGRect frame = pose.frame;
        frame.origin.y = <calculate correct frame>;
        pose.frame = frame;
    }
    return pose;
}

您将负责识别需要调整框架的场景,这可能涉及保持您自己的内部状态。我还没有完成这个逻辑,但我做了一个粗略的测试并且能够获得流畅的动画。

归纳一下,根据我的经验,UICollectionViewFlowLayout 有很多问题,如果你有项目在屏幕上和屏幕外移动以及任何插入,那么有很多极端情况需要处理,删除或移动,我发现滚动我自己的简单布局更容易。如果您不打算进行任何插入、删除或移动,那么覆盖 UICollectionViewFlowLayout 可能是您最好的选择。

如果您需要更多帮助,请告诉我。

编辑

如果您有兴趣查看第 3 方布局,我开源了我的自定义网格布局 VCollectionViewGridLayout并添加了一个示例项目来演示平滑扩展的单元格高度。尝试运行 Expand project .还有一个Sort & Filter project具有动画排序和过滤功能。这两个项目都允许您在流布局和网格布局之间切换,以便您可以看到改进。

关于ios - UICollectionView 动画单元格大小更改会导致不良行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16909105/

相关文章:

css - 在加载 css 之前,Chrome 不会设置动画

ios - 基于 UICollectionViewFlowLayout 的 CoverFlow 布局

ios - Uicollectionview 单元格宽度问题 iOS 10

ios - UILabel 右 anchor 不适用于 ScrollView swift

iphone - 用于 Objective-C 的 Orkut/Flickr 框架

c# - 在 MonoTouch 中使用 Bonjour NSNetService 来自 NSData 的 IP 地址?

ios - 将 SCNNode 的枢轴设置为边界体积中心而不更改节点的位置

javascript - CSS3动画-变换: scale3D on firefox 45. 0

python - 子图中直方图的动画

ios - UICollectionView - 下载图像和有效地重新加载数据,如 Instagram