【问题标题】:Collection view items equal spacing layout集合视图项目等间距布局
【发布时间】:2021-09-07 10:00:23
【问题描述】:

我没有收藏视图布局方面的经验,我决定征求您的意见。我面临下一个问题。我有一个带有自定义单元格的简单集合视图。单元格只有标签,其左右约束等于16。因此单元格的宽度取决于标签的内容。而且我不知道为什么项目有如此奇怪的间距。我在情节提要中设置了间距 - 左右间距 12 点。 实际结果: 我想得到这样的东西: 那么我应该往哪个方向移动呢?感谢您的回答。

更新:运行 iOS 12 的 iPhone 出现奇怪的行为..

【问题讨论】:

    标签: ios swift uicollectionview autolayout uicollectionviewlayout


    【解决方案1】:

    您看到的是 collectionView 布局的默认行为。

    您需要继承 UICollectionViewFlowLayout 才能获得此行为。

    import UIKit
    
    class LeftAlignCellCollectionFlowLayout: UICollectionViewFlowLayout {
        
        private(set) var cellHeight: CGFloat = 36
        init(cellHeight: CGFloat) {
            super.init()
            self.cellHeight = cellHeight
        }
    
        required init?(coder: NSCoder) {
            super.init(coder: coder)
        }
        
        override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
            guard let attributes = super.layoutAttributesForElements(in: rect) else { return nil }
            guard let collectionView = self.collectionView else { return nil }
            
            self.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
            
            var newAttributes = attributes
            var leftMargin = self.sectionInset.left
            var maxY: CGFloat = -1.0
            
            let availableWidth: CGFloat = collectionView.frame.width
            let layout = collectionView.collectionViewLayout
            
            for attribute in attributes {
                if let cellAttribute = layout.layoutAttributesForItem(at: attribute.indexPath) {
                    if cellAttribute.frame.width > availableWidth {
                        cellAttribute.frame.origin.x = 0
                        cellAttribute.frame.size = CGSize(width: availableWidth, height: cellHeight)
                    }
                    else {
                        if cellAttribute.frame.origin.y >= maxY {
                            leftMargin = self.sectionInset.left
                        }
                        
                        var frame = cellAttribute.frame
                        frame.origin.x = leftMargin
                        frame.size.height = cellHeight
                        cellAttribute.frame = frame
                        
                        leftMargin += cellAttribute.frame.width + self.minimumInteritemSpacing
                        maxY = max(cellAttribute.frame.maxY , maxY)
                    }
                    
                    newAttributes.append(cellAttribute)
                }
            }
            
            return newAttributes
        }
    }
    

    现在你可以像这样使用上面的布局了。

    let flowLayout = LeftAlignCellCollectionFlowLayout(cellHeight: 40)
    flowLayout.sectionInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
    flowLayout.minimumInteritemSpacing = 10
    flowLayout.minimumLineSpacing = 10
    collectionView.collectionViewLayout = flowLayout
    

    【讨论】:

    • 非常感谢!这是完美的解决方案。我还必须添加一条语句: if attribute.representedElementCategory == .cell { } 以便正确布局我的标题补充视图。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多