我正在尝试创建一个UICollectionView
表示网格的对象,我想在y轴沿顶部浮动的顶部边缘创建一个标尺(浮动标头视图)。因此,就像在UITableView
s中一样,该视图基本上应该只滚动屏幕顶部的内容。我希望该描述足够清楚。理论上如此多的东西,让我们开始实践吧!
这是我现在正在使用的内容:
GridRulerView
作为其子类的类UICollectionReusableView
。我实现了 viewForSupplementaryElementOfKind::
func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView
{
var reusableHeaderView : UICollectionReusableView!
if kind == GridRulerView.Kind{
reusableHeaderView = collectionView.dequeueReusableSupplementaryViewOfKind(GridRulerView.Kind, withReuseIdentifier: GridRulerView.Kind, forIndexPath: indexPath) as! UICollectionReusableView
}
return reusableHeaderView
}
我有UICollectionViewLayout
以下layoutAttributesForElementsInRect:
方法的自定义:
override func layoutAttributesForElementsInRect(rect: CGRect) -> [AnyObject]? {
var attribs = [UICollectionViewLayoutAttributes]()
for (indexPath, attrs) in self.attributes{
if CGRectIntersectsRect(rect, attrs.frame) {
attribs.append(attrs)
}
}
var headerAttributes = GridViewRulerAttributes(forSupplementaryViewOfKind: GridRulerView.Kind, withIndexPath: NSIndexPath(forItem: 0, inSection: 0))
headerAttributes.zIndex = 500
headerAttributes.frame = CGRectMake(0, self.collectionView!.contentOffset.y, self.preCalculatedContentSize.width, 80)
attribs.append(headerAttributes)
return attribs
}
当我启动该应用程序时,一切看起来都很好,正是我想要的样子。但是,一旦我将collectionView滚动到其范围之外(collectionView的contentOffset =(-0.5,-0.5)<-例如任何负值),我就会崩溃:
***-[UICollectionViewData validateLayoutInRect:],/ SourceCache / UIKit / UIKit-3318.16.25 / UICollectionViewData.m:426中的断言失败
有趣的是,如果将标头视图属性的框架的y属性设置为0而不是变量contentOffset.y(变为负数),则一切正常。
有人知道为什么会这样吗?
这是更有用的错误消息:
***由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'索引路径({length = 2,path = 0-0})上补充项目的布局属性已从索引路径更改为({length = 2,path = 0-0});元素种类:(GridRulerViewKind); 框架=(0 0; 425.227 24); zIndex = 500; 索引路径:({length = 2,path = 0-0}); 元素种类:(GridRulerViewKind); 框架=(0 -5; 425.227 24); zIndex = 500; 而不会使布局无效”
哇,实际上禁用了“所有异常”断点,并且遇到了更多有用的错误:
***由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'索引路径({length = 2,path = 0-0})上补充项目的布局属性已从索引路径更改为({length = 2,path = 0-0});元素种类:(GridRulerViewKind); 框架=(0 0; 425.227 24); zIndex = 500; 索引路径:({length = 2,path = 0-0}); 元素种类:(GridRulerViewKind); 框架=(0 -5; 425.227 24); zIndex = 500; 而不会使布局无效”
现在,我仍然不知道该怎么办,或者在哪里
“使布局无效”
然后,在浏览类似问题时,我在SO上遇到了类似问题,偶然发现了这个简单函数:
override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool{
return true
}
确实,这似乎行得通!不再崩溃!
实际上,这导致集合视图布局在每次滚动时都无效,因此这似乎不是我正在寻找的解决方案...
经过一番研究,我认为不可能创建一个可以自行更改而不使布局无效的补充视图(哪种看起来很合理-布局如何知道只更新标尺视图而无需明确说明, ?)。而且更新每个滚动条的布局太昂贵了。
因此,我想我将创建一个单独的视图,该视图完全独立于集合视图,并且仅侦听集合视图的滚动委托并根据滚动偏移量调整其框架。我认为这种方法在性能方面要高效得多,并且同样易于实施。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句