UICollectionView使用UICollectionViewFlowLayout删除分节符 [英] UICollectionView remove section breaks with UICollectionViewFlowLayout

查看:214
本文介绍了UICollectionView使用UICollectionViewFlowLayout删除分节符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个分为多个部分的数据集,但是,我想在collectionView中显示它,而不会在各部分之间中断。以下是我想要实现的目标:

I have a dataset that is divided into multiple sections, however, I'd like to display this in a collectionView without breaks between sections. Here's an illustration of what I want to achieve:

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

我意识到解决方案可能在于自定义UICollectionViewLayout子类,但我不确定如何实现这样的事情。

I realize the solution likely lies with a custom UICollectionViewLayout subclass, but I'm not sure how to achieve something like this.

谢谢

推荐答案

你是正确的,你需要继承UICollectionViewLayout。
在开始之前要理解的本质是,您需要至少计算集合视图中每个单元格的位置和大小。 UICollectionViewLayout只是一种提供该信息的结构化方式。你得到了结构,但你必须自己提供其他一切。

You are correct that you need to subclass UICollectionViewLayout. The essence to understand before starting is that you need to calculate at least position and size for every cell in the collection view. UICollectionViewLayout is just a structured way to provide that information. You get the structure, but you have to provide everything else yourself.

你需要覆盖4种方法:


  • 准备

  • invalidateLayout

  • layoutAttributesForItemAtIndexPath

  • layoutAttributesForElementsInRect

  • prepare
  • invalidateLayout
  • layoutAttributesForItemAtIndexPath
  • layoutAttributesForElementsInRect

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

One trick is to cache the layout attributes in a lookup table (dictionary):

var cachedItemAttributes = [IndexPath: UICollectionViewLayoutAttributes]()

In 准备,您计算集合中每个indexPath的布局属性:

In prepare, you calculate the layout attributes for each indexPath in your collectionView:

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

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

In invalidateLayout you reset the cached layout attributes and recalculate them:

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

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

In layoutAttributesForItemAtIndexPath you use the lookup table to return the right layout attributes:

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

layoutAttributesForElementsInRect 您过滤查找表中指定矩形内的元素:

In layoutAttributesForElementsInRect you filter your lookup table for the elements within the specified rect:

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

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

The final piece of the puzzle is the actual calculation of the layout attributes. Here I will provide only pseudo-code:

func calculateAttributes() {
    // For each indexpath (you can get this from the collectionView property using numberOfSections and numberOfItems:inSection )
    // calculate the frame, i.e 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
}

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

To answer your question, here is pseudo-code to calculate the position of each cell:

// 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

如果您需要自定义布局可配置,那么如果可用签名需要使用UICollectionViewDelegateFlowLayout足够,或定义自己继承自UICollectionViewDelegateFlowLayout或UICollectionViewDelegate。因为您的协议继承自UICollectionViewDelegateFlowLayout,它本身继承自UICollectionViewDelegate,所以您可以将其直接设置为viewcontroller中的collectionView委托。在自定义集合视图布局中,您只需将委托从UICollectionViewDelegate强制转换为自定义协议即可使用它。请记住处理转换失败或委托未实现协议方法的情况。

If you need your custom layout to be configurable, then either use UICollectionViewDelegateFlowLayout if the available signatures are sufficient, or define your own that inherits from UICollectionViewDelegateFlowLayout or UICollectionViewDelegate. Because your protocol inherits from UICollectionViewDelegateFlowLayout, which itself inherits from UICollectionViewDelegate, you can set it directly as the collectionView delegate in your viewcontroller. In your custom collection view layout you just need to cast the delegate from UICollectionViewDelegate to your custom protocol to use it. Remember to handle cases where the casting fails or where the protocol methods are not implemented by the delegate.

这篇关于UICollectionView使用UICollectionViewFlowLayout删除分节符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆