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

如何用RxSwift根据数据数量动态绘制UICollectionView单元格?

用RxSwift实现UICollectionView空状态占位显示

核心思路

通过转换数据源Observable,将空数组替换为包含占位元素的数组,再在Cell绑定逻辑中区分正常数据和占位元素,实现不同的UI展示。

具体实现

1. 定义数据类型(区分正常数据与占位)

先定义一个枚举封装两种状态的元素,方便后续逻辑区分:

// 替换SampleModel为你实际使用的数据模型类型
enum SampleItem {
    case normal(SampleModel)
    case placeholder
}

2. 转换数据源

对原有的sample Subject做映射处理:空数组时返回包含占位元素的数组,非空则将每个数据包装为normal类型:

let adjustedItems = viewModel.sample
    .map { samples -> [SampleItem] in
        guard !samples.isEmpty else {
            return [.placeholder]
        }
        return samples.map(SampleItem.normal)
    }

3. 绑定到UICollectionView

根据UI复杂度选择以下两种方案之一:

方案一:复用同一个Cell切换UI

如果空状态和正常状态的UI差异较小,可复用同一个Cell,通过控制子视图显隐实现:

// 确保已注册目标Cell
collectionView.register(Cell.self, forCellWithReuseIdentifier: "cell")

adjustedItems.bind(to: collectionView.rx.items(
    cellIdentifier: "cell",
    cellType: Cell.self
)) { index, item, cell in
    switch item {
    case .normal(let sample):
        // 配置正常数据UI
        cell.contentLabel.text = sample.content
        // 隐藏占位相关视图
        cell.placeholderContainer.isHidden = true
    case .placeholder:
        // 配置空状态UI
        cell.placeholderContainer.isHidden = false
        cell.contentLabel.text = nil
        cell.placeholderLabel.text = "暂无元音数据"
    }
}
.disposed(by: disposeBag)

方案二:使用独立Cell类型

如果两种状态UI差异较大,建议使用独立的Cell类:

// 先注册两种Cell
collectionView.register(NormalCell.self, forCellWithReuseIdentifier: "normalCell")
collectionView.register(PlaceholderCell.self, forCellWithReuseIdentifier: "placeholderCell")

adjustedItems.bind(to: collectionView.rx.items) { collectionView, index, item in
    let indexPath = IndexPath(item: index, section: 0)
    switch item {
    case .normal(let sample):
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "normalCell", for: indexPath) as! NormalCell
        cell.configure(with: sample) // 假设NormalCell有对应的配置方法
        return cell
    case .placeholder:
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "placeholderCell", for: indexPath) as! PlaceholderCell
        cell.tipLabel.text = "暂无元音数据"
        return cell
    }
}
.disposed(by: disposeBag)

注意事项

  • 确保你的PublishSubject声明为具体数组类型,比如var sample = PublishSubject<[SampleModel]>(替换SampleModel为实际模型)
  • 初始可给sample发送空数组触发占位Cell显示:viewModel.sample.onNext([])
  • 调整CollectionView布局,保证占位Cell在空状态下能按需求正常展示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 00:22:38