且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

具有不同大小项目的iOS UICollectionView 水平滚动矩形布局?

更新时间:2023-01-04 10:52:42

我建议在 CollectionViewCell(固定尺寸)中使用 StackView 来创建网格布局,如您的帖子所示.

I would suggest using a StackView inside CollectionViewCell(of fixed dimension) to create a grid layout as shown in your post.

下面的GridStackView根据使用方法addCell(view: UIView)添加的视图数量创建一个动态网格布局.

Below GridStackView creates a dynamic grid layout based on the number of views added using method addCell(view: UIView).

将此 GridStackView 添加为 CollectionViewCell 的唯一子视图,将所有边缘固定到侧面,使其完全填充 CollectionViewCell.

Add this GridStackView as the only subview of your CollectionViewCell pinning all the edges to the sides so that it fills the CollectionViewCell completely.

在准备 CollectionViewCell 时,使用 addCell(view: UIView) 方法向其添加平铺视图.

while preparing your CollectionViewCell, add tile views to it using the method addCell(view: UIView).

如果只添加了一个视图,那么它将显示一个占据整个 GridStackView 以及整个 CollectionViewCell 的视图.如果添加了多个视图,它会自动将它们布局在 CollectionViewCell 内部.

If only one view added, then it will show a single view occupying whole GridStackView and so as whole CollectionViewCell. If there is more than one view added, it will automatically layout them in the inside the CollectionViewCell.

您可以调整下面的代码以获得计算行和列的所需布局.当前的实现需要 rowSize 在初始化我用于我的项目之一时提供,您需要稍微修改它以获得所需的布局.

You can tweak the code below to get the desired layout calculating the row and column. Current implementation needed rowSize to be supplied while initializing which I used for one of my project, you need to modify it a bit to get your desired layout.

class GridStackView: UIStackView {
    private var cells: [UIView] = []
    private var currentRow: UIStackView?
    var rowSize: Int = 3
    var defaultSpacing: CGFloat = 5

    init(rowSize: Int) {
        self.rowSize = rowSize
        super.init(frame: .zero)
        translatesAutoresizingMaskIntoConstraints = false
        axis = .vertical
        spacing = defaultSpacing
        distribution = .fillEqually
    }

    required init(coder: NSCoder) {
        super.init(coder: coder)
        translatesAutoresizingMaskIntoConstraints = false
        axis = .vertical
        spacing = defaultSpacing
        distribution = .fillEqually
    }

    private func preapreRow() -> UIStackView {
        let row = UIStackView(arrangedSubviews: [])
        row.spacing = defaultSpacing
        row.translatesAutoresizingMaskIntoConstraints = false
        row.axis = .horizontal
        row.distribution = .fillEqually
        return row
    }

    func removeAllCell() {
        for item in arrangedSubviews {
            item.removeFromSuperview()
        }
        cells.removeAll()
        currentRow = nil
    }

    func addCell(view: UIView) {
        let firstCellInRow = cells.count % rowSize == 0
        if currentRow == nil || firstCellInRow {
            currentRow = preapreRow()
            addArrangedSubview(currentRow!)
        }
        view.translatesAutoresizingMaskIntoConstraints = false
        cells.append(view)
        currentRow?.addArrangedSubview(view)
        setNeedsLayout()
    }
}