如何以编程方式设置具有动态高度和动态单元格宽度的UICollectionView?

时间:2019-11-23 21:37:15

标签: swift

我正在尝试使用动态高度和动态单元格宽度设置UICollectionView,如下图所示:

enter image description here

我只为我的项目使用UIStackViews,所以UICollectionViews对我来说是新的。

1 个答案:

答案 0 :(得分:1)

在这里,您需要通过创建一个扩展UICollectionViewFlowLayout的新类来创建自定义collectionViewLayout,并且在该类中,您将需要重写layoutAttributesForElements(在rect中为CGRect)方法。 在该重写的方法中,基本上,您要做的是通过修改每个单元格的UICollectionViewLayoutAttributes,然后为每个单元格返回新的修改后的UICollectionViewLayoutAttributes,来再次计算每个单元格的位置。

class LeftAlignedCellsCustomFlowLayout:UICollectionViewFlowLayout {

    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {

//get an array of UICollectionViewLayoutAttributes for all the cells
        let attributes = super.layoutAttributesForElements(in: rect)

        var leftMargin = sectionInset.left

        var maxY: CGFloat = 2.0

        let horizontalSpacing:CGFloat = 5

//Modify the UICollectionViewLayoutAttributes for each cell
        attributes?.forEach { layoutAttribute in

            if layoutAttribute.frame.origin.y >= maxY
                || layoutAttribute.frame.origin.x == sectionInset.left {

                leftMargin = sectionInset.left
            }

            if layoutAttribute.frame.origin.x == sectionInset.left {
                leftMargin = sectionInset.left
            }else {
                layoutAttribute.frame.origin.x = leftMargin
            }

            leftMargin += layoutAttribute.frame.width + horizontalSpacing

            maxY = max(layoutAttribute.frame.maxY, maxY)
        }
//return the array of modified UICollectionViewLayoutAttributes
        return attributes
    }
}

然后在您的视图中要将自定义对齐的CollectionView放在其中的位置,请执行以下操作:

  //Let's say you have an IBOutlet of your collectionView as a class-level instance
    @IBOutlet weak var leftAlignedCollectionView: UICollectionView!

//put the following code in the awakeFromNib of your View:
    let layout = LeftAlignedCellsCustomFlowLayout()
    layout.estimatedItemSize = CGSize(width: 1, height: 1)
    layout.minimumLineSpacing = 5
    layout.minimumInteritemSpacing = 5
    leftAlignedCollectionView.collectionViewLayout = layout

现在,您所要做的就是制作一个collectionViewCell,其中的标签内部具有左,右,上,下间距。并且,在单元格类中放入以下代码:

var isHeightCalculated: Bool = false

override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {

        //We need to cache our calculation to prevent a crash.

        if !isHeightCalculated {

            layoutIfNeeded()
            let size = contentView.systemLayoutSizeFitting(layoutAttributes.size)
            var newFrame = layoutAttributes.frame
            newFrame.size.width = CGFloat(ceilf(Float(size.width)))
            layoutAttributes.frame = newFrame
            isHeightCalculated = true

        }
        return layoutAttributes
    }

上述方法的重写使单元有机会修改布局对象提供的属性。

相关问题