【问题标题】:RxSwift: How to populate the data in collection view cell inside the table view using ViewModel?RxSwift:如何使用 ViewModel 在表格视图内的集合视图单元格中填充数据?
【发布时间】:2020-07-31 21:57:47
【问题描述】:

我确实有以下结构:

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

我想了解如何使用 RxSwift - MVVM 结构从/使用视图模型传递数据。

每当我从 API 获得响应时,它应该分别更新表格视图行和关联的集合视图单元格中的数据。

【问题讨论】:

    标签: ios swift mvvm rx-swift


    【解决方案1】:

    最简单的解决方案是使用数组数组。

    例如。假设您的 API 返回:

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

    那么你的视图模型就这么简单:

    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)
    

    【讨论】:

      【解决方案2】:

      这是我刚刚写的一个例子,用来演示如何使用 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())
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-12
        • 2018-07-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多