UICollectionView动画单元格大小变化导致不希望的行为



我有一个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是如此的bug,有这么多的角落案例要对付,如果你有项目移动在屏幕上和任何插入,删除,或移动,我发现它更容易滚动我自己的简单布局。如果您不打算做任何插入、删除或移动,那么重写UICollectionViewFlowLayout可能是您最好的选择。

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

编辑

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

相关内容

  • 没有找到相关文章

最新更新