RxSwift:如何使用ViewModel在表视图内的集合视图单元格中填充数据



我确实有以下结构:

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

我想了解如何使用RxSwift-MVVM structure在这种结构中传递来自/使用视图模型的数据。

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

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

例如。让我们假设您的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)

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

最新更新