Swift中UICollectionViewCell内嵌UICollectionView横向图片布局问题
UICollectionView横向排列图片不符合预期问题排查
我尝试在UICollectionView中实现图片横向排列,并根据图片数量动态调整宽度,但当前效果不符合预期,相关代码及截图说明如下:
视图控制器代码
import UIKit class ViewController: UIViewController,UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout { @IBOutlet weak var texting1: UICollectionView! override func viewDidLoad() { super.viewDidLoad() self.texting1.register(UINib(nibName:"CollectionViewCell1", bundle: nil), forCellWithReuseIdentifier: "CollectionViewCell1") self.texting1.delegate = self self.texting1.dataSource = self texting1.backgroundColor = .red } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 1 } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell1", for: indexPath) as! CollectionViewCell1 return cell } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return CGSize(width: self.view.frame.width, height: 120) } }
输出效果截图:红色背景的外层CollectionView中,黑色背景的子CollectionView内的图片排列未达到横向预期。
CollectionViewCell1代码
import UIKit class CollectionViewCell1: UICollectionViewCell,UICollectionViewDataSource, UICollectionViewDelegate,UICollectionViewDelegateFlowLayout { @IBOutlet weak var userImageColectionView: UICollectionView! override func awakeFromNib() { super.awakeFromNib() self.userImageColectionView.register(UINib(nibName:"CollectionViewCell2", bundle: nil), forCellWithReuseIdentifier: "CollectionViewCell2") userImageColectionView.delegate = self userImageColectionView.dataSource = self userImageColectionView.backgroundColor = .black } var items = ["1", "2", "3", "4"] func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return self.items.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell2", for: indexPath as IndexPath) as! CollectionViewCell2 return cell } // MARK: - UICollectionViewDelegate protocol func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { print("You selected cell #\(indexPath.item)!") } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return CGSize(width: 70, height: 60); } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { return -10 } }
Xib截图:CollectionViewCell1的Xib布局中包含一个用于展示图片的子CollectionView。
CollectionViewCell2代码
class CollectionViewCell2: UICollectionViewCell { @IBOutlet weak var imguserView: UIImageView! override func awakeFromNib() { super.awakeFromNib() imguserView.image = UIImage(systemName: "person.crop.circle") } }
Xib截图:CollectionViewCell2的Xib布局中包含一个UIImageView,用于显示人物头像图标。
预期效果:图片在子CollectionView中横向排列,并且能根据图片数量动态调整整体宽度(数量少则整体宽度窄,数量多则可横向滚动)。
解决方案
问题分析
当前问题核心:
- 子CollectionView未设置横向滚动方向,默认是纵向;
- 使用负间距导致单元格重叠,布局逻辑错误;
- 子CollectionView的约束可能未正确配置,导致空间不足。
修复步骤
- 设置子CollectionView横向滚动
在CollectionViewCell1的awakeFromNib方法中添加滚动方向设置:
override func awakeFromNib() { super.awakeFromNib() self.userImageColectionView.register(UINib(nibName:"CollectionViewCell2", bundle: nil), forCellWithReuseIdentifier: "CollectionViewCell2") userImageColectionView.delegate = self userImageColectionView.dataSource = self userImageColectionView.backgroundColor = .black // 配置横向滚动 if let flowLayout = userImageColectionView.collectionViewLayout as? UICollectionViewFlowLayout { flowLayout.scrollDirection = .horizontal } userImageColectionView.isScrollEnabled = true }
- 修正间距设置
将负的行间距改为合理正值,避免单元格重叠:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { return 10 }
- 确保子CollectionView约束正确
在CollectionViewCell1的Xib中,给userImageColectionView添加约束:
- 顶部、底部、左、右与cell的contentView对齐(或固定高度+左右对齐),保证子CollectionView拥有足够的显示空间。
- 动态调整宽度(可选,非滚动自适应场景)
若需要子CollectionView根据图片数量自动调整宽度(无需滚动),计算总宽度并更新约束:
// 在CollectionViewCell1中添加宽度约束的IBOutlet @IBOutlet weak var collectionViewWidthConstraint: NSLayoutConstraint! func updateCollectionViewWidth() { let itemWidth: CGFloat = 70 let spacing: CGFloat = 10 let totalWidth = itemWidth * CGFloat(items.count) + spacing * CGFloat(max(items.count - 1, 0)) collectionViewWidthConstraint.constant = totalWidth } // 在awakeFromNib或items更新后调用 override func awakeFromNib() { super.awakeFromNib() // ... 其他代码 updateCollectionViewWidth() }
需在Xib中给子CollectionView添加宽度约束,并关联到上述IBOutlet。
效果验证
完成修改后,子CollectionView内的图片会横向排列:数量较少时自适应宽度,数量过多时可横向滚动,完全符合预期效果。
内容的提问来源于stack exchange,提问作者Sham Dhiman
相关产品推荐
相关产品推荐

