Any ideas how to resolve the fact my UICollectionView crashing when scrolling whist rotating?
I am using the following approach for scrolling and rotation separately, and each seem to work fine. I've just noted when doing both things at the same time I can get this crash. So it seems to be something to do with the fact when I rotate the device and the new layout attributes are being calculated within prepareLayout, that the continual scrolling is triggering "invalidateLayoutWithContext(invalidContext)" (see below).
Ideas? Is there a way to put any scrolling responses on-hold (or ignore them) during the rotation?
Rotation Approach In viewWillLayoutSubviews in the view controller I invalidate the whole layout
self.cal.collectionViewLayout.invalidateLayout()
Scrolling Approach To allow me to have a "sticky" decorative view (header) I don't invalidate the whole layout, as it kills performance, but do the following. In the layout class I override shouldInvalidateLayoutForBoundsChange
override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool {
let invalidContext : UICollectionViewLayoutInvalidationContext = self.invalidationContextForBoundsChange(newBounds)
// Keep Header Sticky
invalidContext.invalidateDecorationElementsOfKind(GCCalendarLayoutKind_Decorative1, atIndexPaths: [headerDecorativeIndexPath])
// Apply Invalidation
self.invalidateLayoutWithContext(invalidContext)
// Return normal super return (just in case of future IOS upgrades)
return super.shouldInvalidateLayoutForBoundsChange(newBounds)
}
Note here I'm invalidating the Decorative View (header), whereas the error with the crash is about my supplementary view layouts being different.
Error
2015-10-30 07:14:30.181 test3_collectionview[17086:3102132] * Assertion failure in -[UICollectionViewData validateLayoutInRect:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3512.29.5/UICollectionViewData.m:408 2015-10-30 07:14:30.185 test3_collectionview[17086:3102132] * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'layout attributes for supplementary item at index path ( {length = 2, path = 0 - 0}) changed from index path: ( {length = 2, path = 0 - 0}); element kind: (Decorative1); frame = (0 1085.5; 320 16); zIndex = 1; to index path: ( {length = 2, path = 0 - 0}); element kind: (Decorative1); frame = (0 853.5; 320 16); zIndex = 1; without invalidating the layout' *** First throw call stack:
I am not sure this would be enough but I would give it a try something along these lines (a collection view is a scroll view):
import CoreGraphics
class myController: UIViewController, UIScrollViewDelegate {
var myScrollView = UIScrollView()
override func viewDidLoad() {
self.view.addSubview(myScrollView)
}
// This will capture rotation events
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
self.myScrollView.scrollEnabled = false
coordinator.notifyWhenInteractionEndsUsingBlock( {_ in self.myScrollView.scrollEnabled = true} )
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
}
func scrollViewDidScroll(scrollView: UIScrollView) {
// This will not ignore scroll but perhaps can help keeping things "tidy" and "performant" during rotation. Not sure
if myScrollView.scrollEnabled == false {
let offset = scrollView.contentOffset
myScrollView.setContentOffset(offset, animated: false)
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With