RxDataSources headerView 和 footerView

RxDataSources headerView and footerView

问题:在从网络服务检索结果之前,CollectionView 页眉和页脚未显示。它们在从服务中检索项目后显示。

我想要的结果::在从 api 调用

检索项目之前显示 CollectionView 页眉和页脚

我尝试过的: 在初始 viewDidLoad 上使用带有页眉和页脚的不同数据源,并在加载结果时将该数据源设置为 nil。没用

我的(不太优雅)解决方案: 在 viewDidLoad 上添加 headerView 和 footerView 子视图,并在结果来自服务时将其替换为 collectionView。

itemsLoading.drive(onNext: { loading in 
 if loading {
   view.addSubview(headerView)
   view.addSubview(footerView) 
} else {  
  headerView.removeFromSuperview()
  footerView.removeFromSuperView()
  view.addSubview(collectionView)

这个问题有没有更优雅的解决方案?

我的代码: 只留下与 Rxswift/RxDataSources

相关的部分
struct Input { 

let id: Driver<String>

} 

struct Output {

let items: Driver<[Item]>

}

class ViewModel {

    func transform(input: Input) -> Output {

        let items = networkService.getItems(id: input.id) // async operation
 
        return Output(items: items)
    }
}
class ViewController: UIViewController {

    private let viewModel = ViewModel()
    private let disposeBag = DisposeBag()
    private let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())

    override func viewDidLoad() {
        super.viewDidLoad()
        bindViewModel()
    }

    private func bindViewModel() {

        let dataSource = ViewController.dataSource()
        let id = .just(id)
        let input = Input(id: id)
        let output = viewModel.transform(input: input)

        output.items.map { items in
            items.map { item in
                SectionModel(model: "first Section", items: [item])
            }
        }
        .drive(collectionView.rx.items(dataSource: dataSource))
        .disposed(by: disposeBag)
    }


extension ViewController {

    typealias DataSource = RxCollectionViewSectionedReloadDataSource
    static func dataSource() -> DataSource<SectionModel<String, Item>> {
        .init(
            configureCell: { _, collectionView, indexPath, _ in
                let cell = collectionView.dequeueReusableCell(ofType: UICollectionViewCell.self, for: indexPath)
                return cell
            },
            configureSupplementaryView: { _, collectionView, kind, indexPath in
                switch kind {
                    case UICollectionView.elementKindSectionHeader:
                        let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, kindType: SectionHeader.self, for: indexPath)
                        return header

                    case UICollectionView.elementKindSectionFooter:
                        let footer = collectionView.dequeueReusableSupplementaryView(ofKind: kind, kindType: SectionFooter.self, for: indexPath)
                        return footer
                    default:
                        assert(false, "Unexpected element kind")
                }

            })
    }
}

简单的解决方案,我觉得更优雅,是使用 startWith 发出一个 SectionModel 数组,每个数组都有 0 个项目,但 model 包含正确的值。