滚动旋转时 UICollectionView 崩溃(索引路径处补充项目的布局属性已更改但未失效..)
UICollectionView crashing when scrolling whist rotating (layout attributes for supplementary item at index path changed without invalidating..)
关于如何解决滚动旋转时我的 UICollectionView 崩溃的任何想法?
我正在使用以下方法分别进行滚动和旋转,并且每种方法似乎都可以正常工作。我刚刚注意到同时做这两件事时我会遇到这个崩溃。因此,当我旋转设备并且在 prepareLayout 中计算新的布局属性时,这似乎与以下事实有关,持续滚动正在触发 "invalidateLayoutWithContext(invalidContext)"(见下文)。
想法?有没有办法在轮换期间放置任何滚动响应 on-hold (或忽略它们)?
旋转方法
在视图控制器的 viewWillLayoutSubviews 中,我使整个布局无效
self.cal.collectionViewLayout.invalidateLayout()
滚动方法
为了让我有一个 "sticky" 装饰视图 (header),我不会使整个布局无效,因为它会降低性能,但请执行以下操作。在布局 class 中,我覆盖了 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)
}
请注意,我在这里使装饰视图 (header) 无效,而崩溃的错误是关于我的补充视图布局不同。
错误
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:
我不确定这是否足够,但我会按照以下思路尝试一下(集合视图是滚动视图):
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)
}
}
}
关于如何解决滚动旋转时我的 UICollectionView 崩溃的任何想法?
我正在使用以下方法分别进行滚动和旋转,并且每种方法似乎都可以正常工作。我刚刚注意到同时做这两件事时我会遇到这个崩溃。因此,当我旋转设备并且在 prepareLayout 中计算新的布局属性时,这似乎与以下事实有关,持续滚动正在触发 "invalidateLayoutWithContext(invalidContext)"(见下文)。
想法?有没有办法在轮换期间放置任何滚动响应 on-hold (或忽略它们)?
旋转方法 在视图控制器的 viewWillLayoutSubviews 中,我使整个布局无效
self.cal.collectionViewLayout.invalidateLayout()
滚动方法 为了让我有一个 "sticky" 装饰视图 (header),我不会使整个布局无效,因为它会降低性能,但请执行以下操作。在布局 class 中,我覆盖了 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)
}
请注意,我在这里使装饰视图 (header) 无效,而崩溃的错误是关于我的补充视图布局不同。
错误
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:
我不确定这是否足够,但我会按照以下思路尝试一下(集合视图是滚动视图):
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)
}
}
}