自动调整单元格:单元格宽度等于 CollectionView

AutoSizing cells: cell width equal to the CollectionView

我将 AutoSizing 单元格与 Autolayout 和 UICollectionView 结合使用。

我可以在单元格初始化代码中指定约束条件:

  func configureCell() {
    snp.makeConstraints { (make) in
      make.width.equalToSuperview()
    }
  }

但是,由于尚未将单元格添加到 collectionView,应用程序崩溃了。

问题

  1. cell 生命周期的哪个阶段可以添加 cellwidth?

  2. 约束
  3. 是否有任何默认方式制作 cell's</code>width<code>equal to the widthof thecollectionViewwithout accessing an instance of UIScreenorUIWindow`?

编辑 这个问题不是重复的,因为它不是关于如何使用 AutoSizing 单元格功能,而是在单元格生命周期的哪个阶段应用约束以实现预期结果 when 使用 AutoLayout。

要实现 self-sizing 集合视图单元格,您需要做两件事:

  1. UICollectionViewFlowLayout
  2. 上指定 estimatedItemSize
  3. 在您的手机上实施 preferredLayoutAttributesFitting(_:)

1。在 UICollectionViewFlowLayout

上指定 estimatedItemSize

The default value of this property is CGSizeZero. Setting it to any other value causes the collection view to query each cell for its actual size using the cell’s preferredLayoutAttributesFitting(_:) method. If all of your cells are the same height, use the itemSize property, instead of this property, to specify the cell size instead.

只是一个估计值,用于计算滚动视图的内容大小,请将其设置为合理的值。

let collectionViewFlowLayout = UICollectionViewFlowLayout()
collectionViewFlowLayout.estimatedItemSize = CGSize(width: collectionView.frame.width, height: 100)

2。在您的 UICollectionViewCell 子类

上实现 preferredLayoutAttributesFitting(_:)
override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
    let autoLayoutAttributes = super.preferredLayoutAttributesFitting(layoutAttributes)

    // Specify you want _full width_
    let targetSize = CGSize(width: layoutAttributes.frame.width, height: 0)

    // Calculate the size (height) using Auto Layout
    let autoLayoutSize = contentView.systemLayoutSizeFitting(targetSize, withHorizontalFittingPriority: UILayoutPriority.required, verticalFittingPriority: UILayoutPriority.defaultLow)
    let autoLayoutFrame = CGRect(origin: autoLayoutAttributes.frame.origin, size: autoLayoutSize)

    // Assign the new size to the layout attributes
    autoLayoutAttributes.frame = autoLayoutFrame
    return autoLayoutAttributes
}

您需要实施 sizeForItemAt: 来计算大小。

如果您的单元格具有可变高度,我们还使用了 "sizing cell"。例如:

class MyFancyCell: UICollectionViewCell {
    class func cellSize(_ content: SomeContent, withWidth width: CGFloat) -> CGSize {
        sizingCell.content = content
        sizingCell.updateCellLayout(width)
        return sizingCell.systemLayoutSizeFitting(UILayoutFittingExpandedSize)
    }

    fileprivate static let sizingCell = Bundle.main.loadNibNamed("ContentCell", owner: nil, options: nil)!.first as! ContentCell    

    func updateCellLayout(width: CGFloat) {
        //Set constraints and calculate size    
    }
}