我的应用程序具有UIViewController
类;在此类中,我连接了从情节提要加载的UICollectionView
。
我正在使用UICollectionViewLayout
类创建自定义布局。看起来是这样的:
class MyLayout: UICollectionViewLayout {
override func prepareLayout() {
super.prepareLayout()
}
override func collectionViewContentSize() -> CGSize {
let attributes = super.collectionViewContentSize()
return attributes
}
override func layoutAttributesForElementsInRect(rect: CGRect) -> [AnyObject]? {
let attributes = super.layoutAttributesForElementsInRect(rect) as? [UICollectionViewLayoutAttributes]
return attributes
}
override func layoutAttributesForItemAtIndexPath(indexPath:
NSIndexPath) -> UICollectionViewLayoutAttributes {
let attributes = super.layoutAttributesForItemAtIndexPath(indexPath)
return attributes
}
}
要将UICollectionViewLayout
分配给UICollectionView
,我使用collectionViewLayout
的UICollectionView
属性:myCollectionView.collectionViewLayout = MyLayout()
运行该应用程序后,UICollectionViewCells
不再可见。不过,在分配UICollectionViewLayout
之前,它们是可见的。我现在只能看到UICollectionView
的背景。为什么细胞不再可见?
更新
我仔细查看了自己
UICollectionViewLayoutAttributes
的UICollectionView
,尤其是contentSize
。我打印出它的值,它似乎等于(0.0, 0.0)
。 attributes
的layoutAttributesForElementsInRect
值也等于nil
。绝对是一个红旗。Download the project
最佳答案
首先,您应该使用布局初始化UICollectionView,而不是事后设置它:
var collectionView = UICollectionView(frame: frame, collectionViewLayout: myLayout)
从documentation:
通常,在创建集合视图时指定一个布局对象[...]
接下来,如果您是
UICollectionViewLayout
的子类,则必须实现collectionViewContentSize
并返回您自己的值。在这里,未定义调用super的定义,除非您将UICollectionViewFlowLayout
子类化。子类必须重写此方法,并使用它返回集合视图内容的宽度和高度。这些值表示所有内容的宽度和高度,而不仅仅是当前可见的内容。收集视图使用此信息来配置其自身的内容大小以进行滚动。
这是因为UICollectionViewLayout本身是一个不执行任何操作的抽象类(它应该被子类化)。
UICollectionViewLayout类是抽象基类,您可以将其子类化并用于生成集合视图的布局信息。
同样,您还需要在
layoutAttributesForElementsInRect:
中计算自己的layoutAttributes。最简单的方法是在prepareLayout
方法中计算所需的所有布局,然后再获取所需的布局。这是自定义布局的“核心”:UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath)
为该indexPath创建一个空的layoutAttribute。 frame
属性。 layoutAttributesForElementsInRect:
中,遍历先前实例化的所有已存储的layoutAttributes,并返回其子集frame
与提供的rect
相交的子集。 UICollectionView将要求其dataSource为该方法(通过cellForItemAtIndexPath
)返回的每个layoutAttributes提供一个单元格,并将使用这些layoutAttributes中的frame
属性设置这些单元格的frame
。 如果您既可以阅读Swift也可以阅读Objective-C,则可以看看my sample
UICollectionViewLayout
implementation here,它使UICollectionView模仿iOS日历应用程序的每日视图(screenshot)。如果您的目标是实现一个相当标准的布局(即放置在水平或垂直流动的网格中的元素),则建议您从子类化
UICollectionViewFlowLayout
开始,因为它已经是UICollectionViewLayout
的有效实现,这意味着您可以在大多数方法中使用super
来获取默认值。另外,请阅读here in the official documentation,了解如何创建自己的自定义布局。