如何水平居中调整大小的 UICollectionView 单元格?

Eri*_*uan 5 ios autolayout uicollectionview swift

我有一个 collectionView 并且方向设置为 Horizo​​ntal 并且每个单元格只包含一个 UIlabel 并且它使用自动布局来确定单元格的宽度。

例如,有三个单元格,这是默认行为。

|[x] [xxx] [xxxxxxxxx] |

但是如果所有单元格的总宽度不超过屏幕的宽度,则要求将这三个单元格居中对齐。

第一个单元格的左插图应该是

leftInset = (screen width - (first cell width + second cell width + third cell width + total spaces between the three cells) /) 2

结果是

| [x] [xxx] [xxxxxxxxx] |

我从如何水平居中 UICollectionView 单元格中找到了固定宽度单元格的一个很好的答案,但不适用于自尺码。

如果您愿意提供帮助,我们将不胜感激。

d4R*_*4Rk 5

真的很烦人,Apple 没有为这些东西提供现成的布局......

最后我想出了以下流程布局:

class HorizontallyCenteredCollectionViewFlowLayout: UICollectionViewFlowLayout {
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.scrollDirection = .horizontal
    }

    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        guard let attributes = super.layoutAttributesForElements(in: rect) else { return nil }
        guard let collectionView = self.collectionView,
            let rightmostEdge = attributes.map({ $0.frame.maxX }).max() else { return attributes }

        let contentWidth = rightmostEdge + self.sectionInset.right
        let margin = (collectionView.bounds.width - contentWidth) / 2

        if margin > 0 {
            let newAttributes: [UICollectionViewLayoutAttributes]? = attributes
                .compactMap {
                    let newAttribute = $0.copy() as? UICollectionViewLayoutAttributes
                    newAttribute?.frame.origin.x += margin
                    return newAttribute
            }

            return newAttributes
        }

        return attributes
    }
}
Run Code Online (Sandbox Code Playgroud)

这主要包括以下步骤:

  1. 计算 contentWidth
  2. 计算s和s 宽度margin之间的(左+右)contentWidthcollectionView
  3. 必要时应用边距*,这会导致输入内容

* 负边距意味着内容大于 ,collectionView因此属性应保持不变 => 可滚动并按预期左对齐。