在将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 ,我使用UICollectionViewcollectionViewLayout属性:

 myCollectionView.collectionViewLayout = MyLayout() 

运行应用程序时, UICollectionViewCells不再可见。 但是,在分配UICollectionViewLayout之前,它们是可见的。 我现在只能看到UICollectionView的背景。

为什么细胞不再可见?

更新

我仔细UICollectionViewLayoutAttributes了我的UICollectionView ,特别是contentSize 。 我打印出它的值,似乎等于(0.0, 0.0)layoutAttributesForElementsInRectattributes值也等于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以获得良好的衡量标准:)