我使用以下方法分别滚动和旋转,每个似乎工作正常.我刚刚注意到,在做这两件事的同时我可以得到这个崩溃.因此,当我旋转设备并且在prepareLayout中计算新的布局属性时,似乎与事实有关,即连续滚动触发“invalidateLayoutWithContext(invalidContext)”(见下文).
想法?有没有办法在旋转期间将任何滚动响应置于保持状态(或忽略它们)?
旋转方法
在视图控制器中的viewWillLayoutSubviews中,我使整个布局无效
self.cal.collectionViewLayout.invalidateLayout()
滚动方法
为了让我有一个“粘性”装饰视图(标题)我不会使整个布局无效,因为它会杀死性能,但请执行以下操作.在布局类中,我重写了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) }
请注意,我将装饰视图(标题)无效,而崩溃的错误是关于我的补充视图布局不同.
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) } } }