没有UICollectionViewLayoutAttributes实例为-layoutAttributesForSupplementaryElementOfKind:

标题是我得到的错误,我不知道为什么,但这里有一些信息,所以希望有人在这里可以澄清我。

我已经分类了UICollectionViewFlowLayout因为这节省了我在UICollectionViewFlowLayout为单元格自己计算框架(也许这是一个问题?)。 然后,我使用UICollectionViewLayoutAttributes信息来计算一个补充的视图,放置它,我得到我想要的布局。

我使用performBatchUpdates:completion:添加,删除和更新视图。 插入工作正常,但是删除项目出现在标题中显示的错误。

所以我知道为什么错误发生,但我不知道为什么它应该发生 。 用一个例子来说明导致这个问题的场景

  1. 从1个项目开始,1个补充视图1个部分
  2. 添加两个项目( prepareLayout看3个项目与3补充意见)
  3. 删除项目( prepareLayout看到2个视图和2个补充视图)
  4. layoutAttributesForSupplementaryViewOfKind:atIndexPath:被调用时要求索引path的属性与部分:0和项目:2
  5. 崩溃,因为它要求第三个补充视图的属性,即使早些时候它叫做准备布局设置2个项目和2个补充视图
  6. 举手投降,绝望

所以,我所知道的有问题的function是:

 - (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath { return self.layoutInfo[elementKind][indexPath]; } 

这当然是由UICollectionView的内部networking自动调用,所以我不知道为什么它要求在该索引path的补充视图。

任何人有任何想法? 也许这是我如何使用performBatchUpdates:completion:但删除工作正常,直到添加补充意见。 我可以根据需要提供更多的代码/解释。

我search论坛寻找答案,并遇到了一些build议。 他们没有一个人给我所需要的救济,最后为了达到最后期限,我完全放弃了补充意见。

几个星期后,出于好奇,我再次环顾四周,最终遇到了下面的post ,现在我又回到了补充的观点。

所以,不要忘记返回你的:

 - (NSArray<NSIndexPath *> *)indexPathsToDeleteForSupplementaryViewOfKind:(NSString *)elementKind { return self.removedIndexPaths; } 

到您的collections视图布局。

为了防止崩溃,您可以为所有那些无效的indexPath返回虚拟属性。 像这样的东西可以帮助防止你的崩溃:

 UICollectionViewLayoutAttributes *layoutAttributes = self.layoutInfo[elementKind][indexPath]; // add some safety checks if this access creates an out of bounds issue // create dummy layoutAttributes // the workaround if (layoutAttributes == nil) { UICollectionViewLayoutAttributes *dummyLayoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:elementKind withIndexPath:indexPath]; dummyLayoutAttributes.frame = CGRectZero; dummyLayoutAttributes.hidden = YES; layoutAttributes = dummyLayoutAttributes; } return layoutAttributes; 

这仍然会导致视图堆栈中不应该存在的对象,但它们是隐藏的,不会造成崩溃。 下次UICollectionView更新它的布局时,应该清除旧的隐藏视图。

我认为你应该做一个UICollectionViewLayoutAttributes的对象,并传递该对象的值

 - (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath { UICollectionViewLayoutAttributes*itemAttributes=self.layoutInfo[elementKind][indexPath] // or UICollectionViewLayoutAttributes *itemAttributes = [self.layoutInfo objectAtIndex:indexPath.row]; // or UICollectionViewLayoutAttributes *itemAttributes = [self.layoutInfo objectForKey:@"xyz"]; return itemAttributes; }