簡體   English   中英

RxSwift:如何使用 ViewModel 在表格視圖內的集合視圖單元格中填充數據?

[英]RxSwift: How to populate the data in collection view cell inside the table view using ViewModel?

我確實有以下結構:

- TableView
-- Custom Table View Cell
--- CollectionView
---- Custom CollectionView Cell

我想了解如何使用 RxSwift - MVVM 結構在此結構中的視圖 model 傳遞數據/使用視圖 model。

每當我收到 API 的響應時,它應該分別更新表視圖行和關聯的集合視圖單元格中的數據。

這是我剛剛寫的一個例子,用來演示如何使用 RxSwift 做你想做的事。 重要提示:這是一個粗略的示例,沒有經過優化編寫和測試,我只是使用文本編輯器編寫的,希望對您有所幫助。 如果沒有,我會在有更多時間時嘗試打磨它。

class MyViewModel {
    // Lets say TableData is your model for the tableView data and CollectionData for your collectionView
    public let tableData : PublishSubject<[TableData]> = PublishSubject()
    public let collectionData : PublishSubject<[CollectionData]> = PublishSubject()

    private let disposeBag = DisposeBag()

    func fetchData() {
        // Whenever you get an update from your API or whatever source you call .onNext
        // Lets assume you received an update and stored them on a variable called newShopsUpdate 
        self.tableData.onNext(newTableDataUpdate)
        self.collectionData.onNext(newCollectionDataDataUpdate)
    }
}

class MyViewController: UIViewController {
    var tableData: BehaviorRelay<[TableData]> = BehaviorRelay(value: [])
    var collectionData:  BehaviorRelay<[CollectionData]> = BehaviorRelay(value: [])
    let viewModel = MyViewModel()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Setup Rx Bindings
        viewModel
            .tableData
            .observeOn(MainScheduler.instance)
            .bind(to: self.tableData)
            .disposed(by: DisposeBag())
        viewModel
            .collectionData
            .observeOn(MainScheduler.instance)
            .bind(to: self.collectionData)
            .disposed(by: DisposeBag())

        // Register yours Cells first as usual
        // ...
        // Setting the datasource using RxSwift
        tableData.bind(to: tableView.rx.items(cellIdentifier: "yourCellIdentifier", cellType: costumeTableViewCell.self)) { row, tableData, cell in 
            // Set all the cell properties here
            // Lets also assume you have you collectionView inside one of the cells
            cell.tableData = tableData

            collectionData.bind(to: cell.collectionView.rx.items(cellIdentifier: "yourCellIdentifier", cellType: costumeCollectionViewCell.self)) { row, collectionData, cell in 
                // Set all the cell properties here
                cell.collectionData = collectionData
            }.disposeBag(by: DisposeBag())
        }.disposed(by: DisposeBag())
    }
}

最簡單的解決方案是使用 arrays 數組。

例如。 假設您的 API 返回:

struct Group: Decodable {
    let items: [String]
}

那么你的觀點 model 會像這樣簡單:

func tableViewItems(source: Observable<[Group]>) -> Observable<[[String]]> {
    return source
        .map { $0.map { $0.items } }
}

創建單元格時,您可以使用Observable.just()將內部數組包裝成一個可觀察對象,如下所示:

// in your view controller's viewDidLoad for example.
        tableViewItems(source: apiResponse)
            .bind(to: tableView.rx.items(cellIdentifier: "Cell", cellType: CollectionTableViewCell.self)) { _, element, cell in
                Observable.just(element)
                    .bind(to: cell.collectionView.rx.items(cellIdentifier: "Cell", cellType: UICollectionViewCell.self)) { _, element, cell in
                        let label = (cell.viewWithTag(6969) as? UILabel) ?? UILabel()
                        label.tag = 6969
                        label.text = element
                        label.sizeToFit()
                        cell.addSubview(label)
                }
                .disposed(by: cell.disposeBag)
        }
        .disposed(by: dispsoeBag)

暫無
暫無

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

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