在UICollectionView
装饰和补充观点似乎是一个很大的谜。目前似乎没有示例代码。我设法让两种类型都在自定义布局中工作(有关详细信息,请参阅此post)。只要它们保持在相同的位置,一切都很好(即,如果它们layoutAttributes.frame
没有改变)。
然而,只要我使用已更改的layoutAttributes
重新布局装饰或补充视图,它们就会在视觉上重复 - 即背景中的副本位于原始位置,副本位于新位置。如果我从XIB实例化它们或完全在代码中实例化它们,并且正常单元格不会发生这种行为,那么行为是相同的。
起初我认为这是某种重绘问题,但这些“副本”在重新布局,重绘等方面都存在。但它们不是真正的副本,因为layoutAttributesForDecorationView
等从未被称为它们(仅适用于新地点)。 UICollectionView
中的背景似乎有一些缓存。
有没有人有这个工作或有任何想法。我必须说我是iOS平台的新手,所以它也可以是简单的设置“剪辑绑定”或“清除图形上下文”属性(我试过这些,但它可能是类似的东西)。
这让我发疯,很奇怪,那里绝对没有示例代码。
我在问自己:装修和补充意见是不是要重新定位? (我希望不会)
答案 0 :(得分:11)
嗨,这是一个老问题,但有答案。
实际上,当我实现自己的Layout对象时,我也遇到了这些问题,直到我意识到必须缓存在自定义布局中创建的任何布局属性对象。在文档中实际上有一个非常含糊的引用(我现在记不清楚它的确切位置),这很容易被误解。
基本上,一旦您为索引路径上的单元格请求了layoutAttributes对象,您应该保留属性对象(例如,将其保留在带有索引路径的字典中作为键将执行)并返回相同的属性对象以及所有后续的属性请求。如果不这样做,而是重新创建新的布局属性,批量更新的动画会导致严重的图形故障和人工制品。
答案 1 :(得分:1)
我有同样的问题。 似乎UICOllectionview存在一些错误(这不是我看到的第一个)。 我通过不使用“performBatchUpdates”来修复它。 我丢失了动画 - 但是在列表中没有不需要的视图。
答案 2 :(得分:1)
I had a similar symptom. My problem was that I had accidentally included the supplementary view's reuseID instead of the kindID when creating my custom layout.
Specifically I had this (Wrong)
UICollectionViewLayoutAttributes *attributes =
[UICollectionViewLayoutAttributes
layoutAttributesForSupplementaryViewOfKind:myViewReuseID
withIndexPath:sectionIndexPath];
When I should have this (Right)
UICollectionViewLayoutAttributes *attributes =
[UICollectionViewLayoutAttributes
layoutAttributesForSupplementaryViewOfKind:myViewKindID
withIndexPath:sectionIndexPath];
This meant that prepareForReuse was never getting called, and my old views never went away. Instead they kept piling up.
答案 3 :(得分:0)
我认为Apple至少会在装饰视图的情况下表明他们正在按预期工作。我遇到了同样的问题,因为我正在重新调整最后一个部分,并尝试设置装饰视图以在更改时围绕这些部分。刚开始使用一个简单的视图,只有红色背景,我的应用程序的整个背景变成红色,这让我感到困惑。我随后在装饰视图的布局属性上将alpha更改为0.3f,并且当部分更改时,我能够看到它们彼此层叠。
这真的让我觉得这可能是设计虽然是我在UICollectionView的教程中读到的一句
另一方面,装饰视图是“装饰性的”而不是 数据驱动:想想iBooks应用程序中的书架背景。
关键是装饰视图不是数据驱动的,不管您的数据是否发生变化都不会改变,无论您是否能够在自定义布局中执行此操作。就像书架的情况一样,货架的大小在创建之后不会改变。
答案 4 :(得分:0)
我知道这是一个古老的问题,但是当布局无效时,补充视图出现问题时,我遇到了这个问题。我相信这是一个错误,我通过在我的布局对象中使用invalidateLayout
来修复它并删除补充视图,如下所示:
- (void)invalidateLayout {
[super invalidateLayout];
// Manually remove all suplementary views of a certain type
/**
** This appears to be a BUG. Invalidate view does not remove suplementary view
** from the view hierachy. But they are Orphaned so stay on screen.
**/
for (UIView *subview in [self.collectionView subviews]) {
if ([subview isKindOfClass:[UICollectionReusableView class]]) {
[subview removeFromSuperview];
}
}
}
将UICollectionReusableView
替换为屏幕上剩余的可重复使用视图的类。
希望这有助于某人。