簡體   English   中英

RxDataSources headerView 和 footerView

[英]RxDataSources headerView and footerView

問題:在從網絡服務檢索結果之前,CollectionView header 和頁腳未顯示。 它們在從服務中檢索到項目后顯示。

我想要的結果::在從 api 調用檢索項目之前顯示 CollectionView header 和頁腳

我嘗試過的:使用不同的數據源與 header 和初始 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包含正確的值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM