AutoSizing cells: cell width equal to the CollectionView

吃可爱长大的小学妹 提交于 2019-12-03 00:42:21
Oliver Atkinson

To implement self-sizing collection view cells you need to do two things:

  1. Specify estimatedItemSize on UICollectionViewFlowLayout
  2. Implement preferredLayoutAttributesFitting(_:) on your cell

1. Specifying estimatedItemSize on UICollectionViewFlowLayout

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.

This is just an estimate which is used to calculate the content size of the scroll view, set it to something sensible.

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

2. Implement preferredLayoutAttributesFitting(_:) on your UICollectionViewCell subclass

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
}

You'll need to implement sizeForItemAt: to calculate the size.

We've also used a "sizing cell" if your cells have variable height. Eg:

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    
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!