如何通过代码实现横向CollectionView适配内容并保持轮播效果
问题解决步骤
核心问题定位
你代码里最关键的问题是viewDidLayoutSubviews中的collectionView.frame = view.bounds——这行代码直接覆盖了用SnapKit设置的宽200、高100约束,导致CollectionView强制占满整个屏幕,进而引发单元格垂直堆叠的异常。
修复方案
1. 移除破坏约束的代码
直接删除ViewController中的viewDidLayoutSubviews方法,或者注释掉覆盖frame的代码:
// 删掉整个方法,或者注释掉frame设置行 // override func viewDidLayoutSubviews() { // super.viewDidLayoutSubviews() // collectionView.frame = view.bounds // }
2. 修复Cell的重复布局问题
你的SeatCardCell每次设置viewModel都会新建UIStackView并重复添加到单元格内,多次滚动后会产生冗余子视图。把StackView的初始化移到init方法中,确保只创建一次:
class SeatCardCell: UICollectionViewCell { var viewModel: SeatViewModel? { didSet { configure() } } // MARK: - Properties let seatImageView = UIImageView(image: nil) let seatLabel: CustomLabel = { let label = CustomLabel() return label }() // 把StackView声明为属性,仅初始化一次 private let stackView = UIStackView() // MARK: - Lifecycle override init(frame: CGRect) { super.init(frame: frame) setupStackView() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func setupStackView() { stackView.spacing = 0 stackView.alignment = .center stackView.addArrangedSubview(seatImageView) stackView.addArrangedSubview(seatLabel) addSubview(stackView) seatImageView.snp.makeConstraints { make in make.size.equalTo(40) } stackView.snp.makeConstraints { make in make.edges.equalToSuperview() } } private func configure() { guard let viewModel = viewModel else { return } seatLabel.text = viewModel.text seatLabel.backgroundColor = .cyan seatImageView.image = .strokedCheckmark // 移除seatLabel.sizeToFit(),约束会自动调整标签尺寸 } }
3. 确认CollectionView布局设置
你的FlowLayout已经设置了横向滚动,单元格尺寸的配置也符合需求,保持现有代码即可:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return CGSize(width: 200, height: collectionView.frame.height) }
效果验证
完成上述修改后,CollectionView会保持宽200、高100的尺寸,单元格将横向排列,滚动时即可实现预期的轮播效果,同时整体高度也能控制在100左右。
内容的提问来源于stack exchange,提问作者Dreiohc
相关产品推荐
相关产品推荐

