如何实现UICollectionViewCell超出宽度时自动换行
实现自适应内容宽度的流式UICollectionViewCell换行布局
需求说明
需要实现UICollectionViewCell宽度根据内部内容自适应,单元格水平排列,超出UICollectionView宽度后自动换行,效果如下:

修改方案
1. 调整UICollectionView布局配置
保留UICollectionViewFlowLayout并设置合理间距,确保布局基础逻辑适配流式排列:
var collectionView: UICollectionView = { let layout = UICollectionViewFlowLayout() layout.scrollDirection = .vertical // 设置单元格最小水平间距 layout.minimumInteritemSpacing = 8 // 设置Section内边距 layout.sectionInset = UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16) let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) collectionView.backgroundColor = MSColorFoundation.msClear collectionView.translatesAutoresizingMaskIntoConstraints = false return collectionView }()
2. 重写sizeForItemAt代理方法,计算自适应宽度
替换固定列数的逻辑,根据单元格内容计算实际宽度:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { // 替换为你的数据源文本 let cellText = yourDataSource[indexPath.item] // 匹配cell内部Label的字体属性 let textAttributes: [NSAttributedString.Key: Any] = [ .font: UIFont.systemFont(ofSize: 14) ] // 计算文本可用最大宽度(减去Section内边距) let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout let maxAvailableWidth = collectionView.bounds.width - flowLayout.sectionInset.left - flowLayout.sectionInset.right // 计算文本实际占用尺寸 let textSize = cellText.boundingRect( with: CGSize(width: maxAvailableWidth, height: CGFloat.greatestFiniteMagnitude), options: .usesLineFragmentOrigin, attributes: textAttributes, context: nil ).size // 加上cell内部Label的左右内边距(示例为各12) let finalCellWidth = textSize.width + 24 // 高度固定为60,宽度向上取整避免布局偏差 return CGSize(width: ceil(finalCellWidth), height: 60) }
3. 额外注意事项
- 确保cell内部的UILabel约束正确:Label的leading、trailing与cell边缘添加合适内边距,换行模式设置为
.byTruncatingTail(避免文本换行)。 - 数据源更新后调用
collectionView.reloadData()刷新布局。
内容的提问来源于stack exchange,提问作者Firda Sahidi
相关产品推荐
相关产品推荐

