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

查看:9
本文介绍了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.

谢谢

推荐答案

我发现对我来说,Marmoy 的答案缺少一个额外的元素:

I found that for me, Marmoy's answer is missing one additional element:

覆盖collectionViewContentSize.

overriding collectionViewContentSize.

否则,根据您的 collectionView 的大小,您可能会调用 layoutAttributesForElements(in rect: CGRect),它的宽度或高度为零,这将错过许多单元格.如果您尝试动态调整集合视图中的项目大小,则尤其如此.

Otherwise, depending on the size of your collectionView, you may get a call to layoutAttributesForElements(in rect: CGRect) which has a zero width or height, which will miss many of the cells. This is especially true if you're trying to dynamically size items in the collection view.

所以 Marmoy 的答案更完整的版本是:

So a more complete version of Marmoy's answer would be:

import UIKit

class NoBreakSectionCollectionViewLayout: UICollectionViewLayout {

    var cachedItemAttributes = [IndexPath: UICollectionViewLayoutAttributes]()
    var cachedContentSize = CGSize.zero

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

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

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

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

    override var collectionViewContentSize: CGSize {
        return cachedContentSize
    }

    func calculateAttributes() {
        var y = CGFloat(0)
        var x = CGFloat(0)
        var lastHeight = CGFloat(0)
        let xSpacing = CGFloat(5)
        let ySpacing = CGFloat(2)
        if let collectionView = collectionView, let datasource = collectionView.dataSource, let sizeDelegate = collectionView.delegate as? UICollectionViewDelegateFlowLayout {
            let sections = datasource.numberOfSections?(in: collectionView) ?? 1
            for section in 0..<sections {
                for item in 0..<datasource.collectionView(collectionView, numberOfItemsInSection: section){
                    let indexPath = IndexPath(item: item, section: section)
                    let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
                    if let size = sizeDelegate.collectionView?(collectionView, layout: self, sizeForItemAt: indexPath) {
                        if x > 0 && (x + size.width + xSpacing) > collectionView.bounds.width {
                            y += size.height + ySpacing
                            x = CGFloat(0)
                        }
                        attributes.frame = CGRect(x: x, y: y, width: size.width, height: size.height)
                        lastHeight = size.height
                        x += size.width + xSpacing
                    }
                    cachedItemAttributes[indexPath] = attributes
                }
            }
            cachedContentSize = CGSize(width: collectionView.bounds.width, height: y + lastHeight)
        }

    }
}

此外,在上面的示例中实现 UICollectionViewDelegateFlowLayout 对您的委托很重要...或者,如果您知道布局中的项目大小而不知道单元格内容,则可以只计算它们.

Additionally, it's important for your delegate to implement UICollectionViewDelegateFlowLayout in the example above... Alternately, you can just calculate item sizes in the Layout if you know them without knowing about the cell content.

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

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