Ios6 initialLayoutAttributesForAppearingItemAtIndexPath为所有可见单元格激发,而不仅仅是插入的单元格

Ios6 initialLayoutAttributesForAppearingItemAtIndexPath为所有可见单元格激发,而不仅仅是插入的单元格,ios6,uicollectionview,Ios6,Uicollectionview,有人看到这个问题的一个像样的答案吗 initialLayoutAttributesForAppearingItemAtIndexPath似乎正在为所有可见单元格调用,而不仅仅是为插入的单元格调用。根据: 对于移动的项目,集合视图使用标准方法检索项目的更新布局属性。对于要插入或删除的项目,“集合”视图会调用一些不同的方法,您应该覆盖这些方法以提供适当的布局信息 听起来不像是发生了什么。。。其他单元格没有被插入,它们正在被移动,但它正在调用initiallayouttributesforappear

有人看到这个问题的一个像样的答案吗

initialLayoutAttributesForAppearingItemAtIndexPath
似乎正在为所有可见单元格调用,而不仅仅是为插入的单元格调用。根据:

对于移动的项目,集合视图使用标准方法检索项目的更新布局属性。对于要插入或删除的项目,“集合”视图会调用一些不同的方法,您应该覆盖这些方法以提供适当的布局信息

听起来不像是发生了什么。。。其他单元格没有被插入,它们正在被移动,但它正在调用
initiallayouttributesforappearinGitematindexPath
,用于移动的单元格


我见过使用
prepareForCollectionViewUpdates:
跟踪正在更新哪些索引路径并仅更改这些索引路径的解决方案,但这似乎有点奇怪,因为它会重新出现在他们自己的文档中。还有其他人找到更好的方法吗?

你并不孤单。UICollectionViewLayout头文件注释使事情变得更清楚

对于失效前屏幕上的每个元素, 将调用FinallYoutAttributesForDisappearingXXX并 从屏幕上的内容到这些最终属性的动画设置

对于失效后屏幕上的每个元素, 出现XXX的InitialLayoutAttribute将被称为动画 从初始属性设置到屏幕上显示的内容

基本上,在动画块开始之前,会为屏幕上的每个项目调用
finalLayoutAttributesForDisappearingItemAtIndexPath
,在动画块结束之后,会为每个项目调用
initiallayouttributesforappearingitematindexpath
。由您来缓存
UICollectionViewUpdateItem
中发送的
prepareForCollectionViewUpdates
对象数组,这样您就知道如何设置初始和最终属性。在我的例子中,我将以前的布局矩形缓存在
prepareLayout
中,以便知道要使用的正确初始位置

有一件事让我感到困惑,那就是您应该使用super的
initiallayouttributesforAppearinGitematindexPath的实现,并修改它返回的属性。我只是在我的实现中调用了
layouttributesforItematindexPath
,动画无法工作,因为布局位置不同。

我发现这很有帮助。
作者还修复了WWDC
圆形布局
示例和

感兴趣的方法:

-(void)prepareForCollectionViewUpdates:(NSArray*)updateItems
{
//跟踪插入和删除索引路径
[super prepareForCollectionViewUpdates:updateItems];
self.deleteIndexPath=[NSMutableArray];
self.insertIndexPaths=[NSMutableArray];
对于(UICollectionViewUpdateItem*在updateItems中更新)
{
if(update.updateAction==UICollectionUpdateActionDelete)
{
[self.deleteIndexPaths addObject:update.indexPathBeforeUpdate];
}
else if(update.updateAction==UICollectionUpdateActionInsert)
{
[self.insertIndexPaths addObject:update.indexPathAfterUpdate];
}
}
}
-(无效)FinalizeCollectionViewUpdate
{
[super FinalizeCollectionViewUpdate];
//释放插入和删除索引路径
self.deleteIndexPaths=nil;
self.insertIndexPaths=nil;
}
//注意:方法名称已更改
//此外,所有可见单元格(不仅仅是插入的单元格)和
//甚至在删除单元格时也会被调用!
-(UICollectionViewLayoutAttributes*)初始LayoutAttributes for AppearinGitemAtIndexPath:(NSIndexPath*)itemIndexPath
{
//一定要叫超级
UICollectionViewLayoutAttributes*属性=[super InitialLayoutAttributes for AppearinGiteMatIndexPath:itemIndexPath];
if([self.insertindexpath containsObject:itemIndexPath])
{
//仅更改插入单元格上的属性
如果(!属性)
attributes=[self-layouttributesforItemAtIndexPath:itemIndexPath];
//配置属性。。。
attributes.alpha=0.0;
attributes.center=CGPointMake(_center.x,_center.y);
}
返回属性;
}
//注意:方法名称已更改
//此外,所有可见单元格(不仅仅是已删除的单元格)和
//甚至在插入单元格时也会被调用!
-(UICollectionViewLayoutAttributes*)FinallyoutAttributesForDisappearinGitemAtIndexPath:(NSIndexPath*)itemIndexPath
{
//到目前为止,在这里打电话给super并不是绝对必要的,但是把它留在家里
//适当地
UICollectionViewLayoutAttributes*attributes=[super finalLayoutAttributesForDisappearingItemAtIndexPath:itemIndexPath];
if([self.deleteIndexPaths containsObject:itemIndexPath])
{
//仅更改已删除单元格上的属性
如果(!属性)
attributes=[self-layouttributesforItemAtIndexPath:itemIndexPath];
//配置属性。。。
attributes.alpha=0.0;
attributes.center=CGPointMake(_center.x,_center.y);
attributes.transform3D=CATTransformM3dMakeScale(0.1,0.1,1.0);
}
返回属性;
}

如果您已经子类化了
UICollectionViewFlowLayout
,则可以调用
super
实现。获得默认初始布局后,可以检查
0
.alpha
。如果
alpha
不是
0
,则单元格正在移动,如果
0
则正在插入


我知道这有点像黑客,但它很有效请确保您在Swift 3中使用了新的方法签名。自动更正不适用于此方法:

func initialLayoutAttributesForAppearingItem(at itemIndexPath: IndexPath) -> UICollectionViewLayoutAttributes?

我也很难理解这一点。每次我更改集合视图时,都会重新加载所有可见单元格,并且