UICollectionView删除部分与UICollectionViewFlowLayout中断

我有一个数据集被分为多个部分,但是,我想显示在一个集合查看没有中断部分。 这里是我想要实现的一个例子:

Instead of: 0-0 0-1 0-2 0-3 1-0 1-1 2-0 3-0 I want: 0-0 0-1 0-2 0-3 1-0 1-1 2-0 3-0 

我意识到解决scheme可能在于一个自定义的UICollectionViewLayout子类,但我不知道如何实现这样的东西。

谢谢

你是正确的,你需要inheritanceUICollectionViewLayout。 在开始之前要了解的基本知识是,您需要至less计算集合视图中每个单元格的位置和大小。 UICollectionViewLayout只是提供这些信息的结构化方式。 你得到的结构,但你必须自己提供一切。

有4种方法需要覆盖:

  • 准备
  • 的invalidateLayout
  • layoutAttributesForItemAtIndexPath
  • layoutAttributesForElementsInRect

一个技巧是将布局属性caching在查找表(字典)中:

 var cachedItemAttributes = [IndexPath: UICollectionViewLayoutAttributes]() 

准备工作中 ,您可以为您的collectionView中的每个indexPath计算布局属性:

 override func prepare() { super.prepare() calculateAttributes() } 

invalidateLayout中,您重置caching的布局属性并重新计算它们:

 override func invalidateLayout() { super.invalidateLayout() cachedItemAttributes = [:] calculateAttributes() } 

layoutAttributesForItemAtIndexPath中,您使用查找表来返回正确的布局属性:

 override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { return cachedItemAttributes[indexPath] } 

layoutAttributesForElementsInRect中,您可以筛选指定矩形内元素的查找表:

 override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { return cachedItemAttributes.filter { rect.intersects($0.value.frame) }.map { $0.value } } 

拼图的最后一部分是布局属性的实际计算。 这里我只提供伪代码:

 func calculateAttributes() { // For each indexpath (you can get this from the collectionView property using numberOfSections and numberOfItems:inSection ) // calculate the frame, ie the origin point and size of each cell in your collectionView and set it with UICollectionViewLayoutAttributes.frame // There are many other properties on UICollectionViewLayoutAttributes that you can tweak for your layout, but frame is a good starting point from which you can start experimenting. // Add the layout attributes to the lookup table // end loop } 

要回答你的问题 ,这里是伪代码来计算每个单元格的位置:

 // If width of cell + current width of row + spacing, insets and margins exceeds the available width // move to next row. // else // cell origin.x = current width of row + interitem spacing // cell origin.y = number of rows * (row height + spacing) // endif 

如果您需要自定义布局是可configuration的,那么如果可用的特征码足够,则使用UICollectionViewDelegateFlowLayout,或者定义从UICollectionViewDelegateFlowLayout或UICollectionViewDelegateinheritance的自己的布局。 因为你的协议inheritance自UICollectionViewDelegateFlowLayout,而UICollectionViewDelegateFlowLayout本身是从UICollectionViewDelegateinheritance的,所以你可以直接在你的viewcontroller中将它设置为collectionView委托。 在您的自定义集合视图布局中,您只需将来自UICollectionViewDelegate的委托转换为您的自定义协议即可使用它。 请记住处理投射失败或协议方法未由代表实施的情况。