UICollectionView动画单元格大小更改会导致意外行为

时间:2013-06-04 02:54:05

标签: 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:方法很好地动画了这个大小的变化。然而!当动画发生时,扩展单元格可能会导致屏幕底部的部分可见单元格离开屏幕。

如果是这种情况,我随后会折叠此单元格,现在关闭屏幕单元格将在没有动画的情况下捕捉到其旧位置,而所有其他可见单元格将根据需要进行动画处理。我的直觉说这是正确的行为,因为在执行折叠动画时单元格不在屏幕上,并且没有包含在动画渲染过程中。我的问题变成了,我该如何防止这种情况发生?

我更喜欢所有细胞一起动画,无论它们是否在屏幕外。有什么想法吗?

1 个答案:

答案 0 :(得分:27)

这是一个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可能是您最好的选择。

如果您需要更多帮助,请与我联系。

修改

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