我在CollectionView中使用CustomLayout完成了一个View。在iOS6中它运行得很好,但是iOS7会抛出这样的异常。
由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因是:
索引路径({length = 2,path = 0 - 0})上的补充项的'布局属性从CustomSupplementaryAttributes:0xd1123a0索引路径更改:(NSIndexPath:0xd112580 {length = 2,path = 0 - 0});元素种类:(标识符); frame =(0 0; 1135.66 45); zIndex = -1;到CustomSupplementaryAttributes:0xd583c80索引路径:(NSIndexPath:0xd583c70 {length = 2,path = 0 - 0});元素种类:(标识符); frame =(0 0; 1135.66 45); zIndex = -1;没有使布局'
无效
答案 0 :(得分:59)
在iOS 10中,引入了一项新功能,它是Cell Prefetching
。它会让SupplementaryView
的动态位置崩溃。要以旧行为运行,需要禁用prefetchingEnabled
。它默认情况下是iOS 10中的true
。
// Obj-C
// This function is available in iOS 10. Disable it for dynamic position of `SupplementaryView `.
if ([self.collectionView respondsToSelector:@selector(setPrefetchingEnabled:)]) {
self.collectionView.prefetchingEnabled = false;
}
// Swift
if #available(iOS 10, *) {
// Thanks @maksa
collectionView.prefetchingEnabled = false
// Swift 3 style
colView.isPrefetchingEnabled = false
}
我讨厌这个问题。我花了2天时间来解决这个问题。 关于Cell Pre-fetch @iOS 10的参考。
@Away Lin is right.。我通过实现该委托方法解决了同样的问题。
我的Custom UICollectionViewLayout
会修改layoutAttributesForElementsInRect
中的属性。部分位置是动态的,而不是静态的。所以,我收到关于layout attributes for supplementary item at index path ... changed from ... to ...
的警告。在更改之前,应调用invalideLayout
相关方法。
并且,在实现此委托方法以返回true
之后,在滚动invalidateLayoutWithContext:
时将调用方法UICollectionViewLayout
。默认情况下,它返回false
。
- (BOOL) shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
return YES;
}
返回值 如果集合视图需要布局更新,则返回true;如果是,则返回false 布局不需要改变。
讨论此方法的默认实现返回false。 子类可以覆盖它并返回基于的适当值 集合视图边界的更改是否需要更改 细胞布局和补充观点。
如果集合视图的边界发生更改并且此方法返回 如果是,集合视图通过调用使布局无效 invalidateLayoutWithContext:method。
可用性适用于iOS 6.0及更高版本。
A nice example project on GitHub, for custom UICollectionViewLayout.
答案 1 :(得分:18)
您需要在更新前使现有布局无效,请参阅错误消息的结尾:
不会使布局失效'
[collectionViewLayout invalidateLayout];
答案 2 :(得分:11)
我遇到了同样的例外:在iOS 7中,您现在需要覆盖UICollectionViewLayoutAttributes子类中的继承isEqual:
,如Apple文档here中所述。
答案 3 :(得分:4)
我通过覆盖UICollectionViewFlowLayout
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBound
返回YES
答案 4 :(得分:1)
我也有这个问题,因为我的代码依赖于集合视图的内容大小。我的代码是通过collectionView!.contentSize
而不是collectionViewContentSize
访问内容大小。
前者使用collectionView
的{{1}}属性,而后者使用自定义实现的布局属性。在我的代码中,第一次要求布局属性时,UICollectionViewLayout
尚未设置。
答案 5 :(得分:1)
我不确定如何或为什么,但是这似乎在iOS 12中已解决,同时支持补充视图大小调整和预取。对我来说,诀窍是确保事情以正确的顺序进行。
这是可拉伸标头视图的有效实现。注意statuses = str(input()).split(',')
query = str(input())
positions = [i for i, status in enumerate(statuses) if status == query]
for i in positions:
print(i + 1)
if not positions:
print('not found')
中报头大小调整的实现:
layoutAttributesForElements(in rect: CGRect)
P.S .:我知道此时缓存实际上没有任何作用:)
答案 6 :(得分:0)
选择CollectionView和Goto属性检查器。取消选中已启用预压缩复选框。这已解决我的问题。 Screenshot