You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用UICollectionViewCompositionalLayout适配DiffableDataSource不同宽度单元格

横向滚动UICollectionView混排不同宽度单元格布局问题

现状说明

  • 现有横向滚动UICollectionView,原本仅加载1种固定尺寸单元格,现需改造为加载两种固定宽度不同、高度完全一致的单元格,其中BigCell宽度大于常规RegularCell
  • 已完成数据源逻辑改造:通过判断MediaItem模型的isLongDuration属性取值,在对应indexPath位置加载对应类型单元格;目前BigCell仅设置了与RegularCell不同的黑色背景做区分,尚未调整尺寸,已验证单元格类型加载逻辑完全正确
  • 单元格排布无固定规律,加载类型完全由数据源数组中对应条目的isLongDuration属性值决定,截图中呈现的规律交替效果仅为测试数据特例
  • 早期测试发现,直接为BigCell设置更大宽度会导致UICollectionView整体布局错乱,暂未检索到如何根据DiffableDataSource加载的单元格类型调整UICollectionViewCompositionalLayout配置的相关参考资料

当前collectionView运行截图,黑色单元格为待调整宽度的BigCell

注:图中垂直红线是用于标记UICollectionView中点的静态视图,与布局逻辑无关,无需关注

现有实现代码

DiffableDataSource 配置

private func configureDataSource() {
    
    dataSource = UICollectionViewDiffableDataSource<Int, MediaItem>(
      collectionView: collectionView) { [unowned self] collectionView, indexPath, media in  
          guard !media.isLongDuration else {
          let cell = collectionView.dequeueReusableCell(
            withReuseIdentifier: String(describing: BigCell.self),
            for: indexPath
          ) as! BigCell
        }
        
        let cell = collectionView.dequeueReusableCell(
          withReuseIdentifier: String(describing: RegularCell.self),
          for: indexPath
        ) as! RegularCell
       
        return configuredCellInTimeline(
          collectionView,
          for: cell,
          at: indexPath,
          with: media
        )
      }
 
    var snapshot = NSDiffableDataSourceSnapshot<Int, MediaItem>()
    snapshot.appendSections([0])
    dataSource.apply(snapshot, animatingDifferences: false)
}

CompositionalLayout 配置

private lazy var collectionViewLayout: UICollectionViewLayout = {
    let configuration = UICollectionViewCompositionalLayoutConfiguration()
    configuration.scrollDirection = .horizontal
    
    let layout = UICollectionViewCompositionalLayout(
      sectionProvider: { sectionIndex, environment -> NSCollectionLayoutSection? in
        let itemSize = NSCollectionLayoutSize(widthDimension: .absolute(95),
                                              heightDimension: .absolute(170))
        let item = NSCollectionLayoutItem(layoutSize: itemSize)
        
        let groupSize = NSCollectionLayoutSize(widthDimension: .absolute(100),
                                               heightDimension: .absolute(100))
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize,
                                                       subitems: [item])
        
        let section = NSCollectionLayoutSection(group: group)
        
        return section
      },
      configuration: configuration
    )
    
    return layout
}()

待解决问题

当前CompositionalLayout配置写死了统一的单元格尺寸,无法适配两种不同固定宽度的单元格混排需求,直接修改cell自身frame会引发布局错乱,求该场景的可落地方案。

内容的提问来源于stack exchange,提问作者Shyne

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 20:21:27