Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
407 views
in Technique[技术] by (71.8m points)

uicollectionviewlayout - UICollectionView exception in UICollectionViewLayoutAttributes from iOS7

I have done a View in CollectionView with CustomLayout. In iOS6 it worked great but iOS7 it throws an exception like this.

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason:

'layout attributes for supplementary item at index path ( {length = 2, path = 0 - 0}) changed from CustomSupplementaryAttributes: 0xd1123a0 index path: (NSIndexPath: 0xd112580 {length = 2, path = 0 - 0}); element kind: (identifier); frame = (0 0; 1135.66 45); zIndex = -1; to CustomSupplementaryAttributes: 0xd583c80 index path: (NSIndexPath: 0xd583c70 {length = 2, path = 0 - 0}); element kind: (identifier); frame = (0 0; 1135.66 45); zIndex = -1; without invalidating the layout'

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

iOS 10

At iOS 10, a new feature is introduced, it is Cell Prefetching. It will let dynamic position of SupplementaryView crash. In order to run in the old behavior, it needs to disable prefetchingEnabled. It's true by default at iOS 10.

// 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   
}

I hate this problem. I spend 2 days for this problem. A reference about Cell Pre-fetch @iOS 10.


iOS 9 and before ...

@Away Lin is right.. I solve the same problem by implementing that delegate method.

My Custom UICollectionViewLayout will modify the attributes in layoutAttributesForElementsInRect. The section position is dynamic, not static. So, I obtain warnings about the layout attributes for supplementary item at index path ... changed from ... to .... Before the changes, invalideLayout related methods should be called.

And, after implementing this delegate method to return true, the method invalidateLayoutWithContext: will be called when scrolling the UICollectionViewLayout. By default, it returns false.

- (BOOL) shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
    return YES;
}

From Apple Docs

Return Value true if the collection view requires a layout update or false if the layout does not need to change.

Discussion The default implementation of this method returns false. Subclasses can override it and return an appropriate value based on whether changes in the bounds of the collection view require changes to the layout of cells and supplementary views.

If the bounds of the collection view change and this method returns true, the collection view invalidates the layout by calling the invalidateLayoutWithContext: method.

Availability Available in iOS 6.0 and later.


And more ...

A nice example project on GitHub, for custom UICollectionViewLayout.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...