来自iOS7的UICollectionViewLayoutAttributes中的UICollectionView异常

时间:2013-10-06 10:42:03

标签: uicollectionview uicollectionviewlayout

我在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;没有使布局'

无效

7 个答案:

答案 0 :(得分:59)

iOS 10

在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的参考。

iOS 9及之前......

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

From Apple Docs

  

返回值   如果集合视图需要布局更新,则返回true;如果是,则返回false   布局不需要改变。

     

讨论此方法的默认实现返回false。   子类可以覆盖它并返回基于的适当值   集合视图边界的更改是否需要更改   细胞布局和补充观点。

     

如果集合视图的边界发生更改并且此方法返回   如果是,集合视图通过调用使布局无效   invalidateLayoutWithContext:method。

     

可用性适用于iOS 6.0及更高版本。

还有更多......

A nice example project on GitHub, for custom UICollectionViewLayout.

答案 1 :(得分:18)

您需要在更新前使现有布局无效,请参阅错误消息的结尾:

  

不会使布局失效'

[collectionViewLayout invalidateLayout];

Apple Documentation for UICollectionViewLayout

答案 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