UICollectionViewanimation单元大小更改会导致不希望的行为

我有一个UICollectionViewController使用标准的UICollectionViewFlowLayout来显示一个垂直的单元格列。 我试图在单元格点击时在单元格上创build展开/折叠animation。 我使用下面的代码来完成这个:

 - (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; } 

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

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

然后performBatchUpdates:completiong:方法dynamic地改变这个尺寸的改变。 然而! 当animation发生时,展开的单元格可能会使屏幕底部的部分可见单元格离开屏幕。

如果是这种情况,我随后折叠这个单元格,现在的非屏幕单元格将会捕捉到它的旧位置,而没有animation,而所有其他可见单元格将根据需要animation。 我的直觉说,这是正确的行为,因为当崩溃animation正在执行时单元格不在屏幕上,并且不包含在animation呈现过程中。 我的问题变成了,我如何防止这种情况发生?

我宁愿所有的细胞一起animation,无论他们是否在屏幕外。 有什么想法吗?

这是一个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; } 

您将负责识别需要调整框架的场景,这可能涉及保持您自己的内部状态。 我没有通过这个逻辑,但我做了一个粗略的testing,并能够得到stream畅的animation。

概括一下,根据我的经验, UICollectionViewFlowLayout是如此的UICollectionViewFlowLayout ,如果你有物品在屏幕上移动和移出,以及任何插入,删除或移动,我发现更容易推出我自己的简单布局。 如果你不打算做任何插入,删除或移动,那么覆盖UICollectionViewFlowLayout可能是你最好的select。

让我知道如果你需要更多的帮助。

编辑

如果你有兴趣查看第三方的布局,我打开我的自定义网格布局VCollectionViewGridLayout,并添加了一个示例项目,演示平滑扩展单元格高度。 尝试运行展开项目 。 还有一个sorting和筛选项目animationsorting和过滤。 这两个项目让你切换stream布局和网格布局,所以你可以看到改善。