在将UICollectionViewLayout分配给UICollectionView之后,为什么UICollectionViewCells不再可见?
我的应用程序有一个UIViewController
类; 在这个类中我连接从Storyboard加载的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
,我使用UICollectionView
的collectionViewLayout
属性:
myCollectionView.collectionViewLayout = MyLayout()
运行应用程序时, UICollectionViewCells
不再可见。 但是,在分配UICollectionViewLayout
之前,它们是可见的。 我现在只能看到UICollectionView
的背景。
为什么细胞不再可见?
更新
我仔细UICollectionViewLayoutAttributes
了我的UICollectionView
,特别是contentSize
。 我打印出它的值,似乎等于(0.0, 0.0)
。 layoutAttributesForElementsInRect
的attributes
值也等于nil
。 绝对是一面红旗。
下载项目
首先,您应该使用布局初始化UICollectionView,而不是之后设置它:
var collectionView = UICollectionView(frame: frame, collectionViewLayout: myLayout)
从文档 :
通常在创建集合视图时指定布局对象[…]
接下来,如果您UICollectionViewLayout
,则必须实现collectionViewContentSize
并返回自己的值。 除非您是UICollectionViewFlowLayout
的子类,否则此处调用super是未定义的。
子类必须覆盖此方法并使用它来返回集合视图内容的宽度和高度。 这些值表示所有内容的宽度和高度,而不仅仅是当前可见的内容。 集合视图使用此信息配置其自己的内容大小以进行滚动。
那是因为UICollectionViewLayout本身就是一个什么都不做的抽象类 (它意味着要被子类化)。
UICollectionViewLayout类是一个抽象基类,您可以将其子类化并用于生成集合视图的布局信息。
同样,您还需要在layoutAttributesForElementsInRect:
计算自己的layoutAttributesForElementsInRect:
. 最简单的方法是在prepareLayout
方法中计算所有必需的布局,然后获取您需要的布局。 这是自定义布局的“核心”:
- 向代表询问您必须在collectionView中显示的元素数量。
- 对于每个元素,首先创建正确的indexPath,然后使用
UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath)
为该indexPath创建一个空的layoutAttribute。 - 计算并设置该layoutAttribute的
frame
属性。 - 将layoutAttribute存储在声明为MutableArray的私有属性中。
- 在
layoutAttributesForElementsInRect:
,迭代先前实例化的所有存储的layoutAttributes,并返回其frame
与提供的rect
相交的那些子集。 UICollectionView将要求其dataSource为该方法返回的每个layoutAttributes提供一个单元格 (通过cellForItemAtIndexPath
),并使用这些layoutAttributes中的frame
属性设置这些单元格的frame
。
如果您可以阅读Objective-C以及Swift,您可以在这里查看我的示例UICollectionViewLayout
实现 ,这使得UICollectionView模仿iOS日历应用程序的每日视图( 屏幕截图 )。
如果您的目标是实现一个相当标准的布局(即布置在水平或垂直流动的网格中的元素),我建议您从子类化UICollectionViewFlowLayout
开始,因为它已经是UICollectionViewLayout
的有效实现,这意味着你可以在大多数方法中使用super
来获取默认值。
另外, 在官方文档中有关如何创建自己的自定义布局的详细信息。
我想你几乎可以保持一切完全相同。 将自定义布局的类类型更改为UICollectionViewFlowLayout
。
class myLayout: UICollectionViewFlowLayout { //all your code here }
另外,将myLayout更改为MyLayout以获得良好的衡量标准:)