RxSwift MVVM tableview / collectionview具有代表状态的用户输入单元

时间:2019-05-09 09:55:35

标签: rx-swift rx-cocoa rxdatasources

我对你们每个人都有一个要求。我想创建collectionview / tableview,它将在单元格中有用户输入。来自那些输入的值的混合将代表状态。我想观察该状态,如果满足某些条件,我想重新创建所有单元格。我创建了一个非常简单的应用程序,在其中演示了如何尝试实现该应用程序,但是我收到了重新进入警告,我很乐意为此找到您的想法/最佳实践。这是您可以签出的仓库。

https://github.com/beretis/CollectionViewTest

PS:我正在使用RxData源,我想确切地知道是什么导致了这种重新进入(我有主意)

1 个答案:

答案 0 :(得分:0)

我以您的方式发送了拉取请求。

回答这个问题的关键是在视图模型中有两个Observable。一个代表每个单元的编程状态(用户未输入的内容),另一个代表每个单元的用户输入状态。您使用某种ID值(我使用UUID)来连接来自这两个Observable的数据。因此对于您的特定示例,集合的视图模型应如下所示:

typealias CellID = UUID

struct StaticCellState {
    let id: CellID
    let placeholder: String
}

struct CollectionViewModel {
    let cells: Observable<[StaticCellState]>
    let cellStates: Observable<[CellID: String]>
}

可观察到的cells包含占位符和单元格ID。这是单元在配置时使用的数据,并且在该配置的生命周期内不会更改(如果单元被重用,它可能会更改。)仅在您要添加/删除单元或更改单元时才更新。特定单元格的占位符值。

cellStates观察值包含最新的用户输入值,并且每次用户在单元格的文本字段之一中键入时都会更新。

然后,您通过从两个可观察对象传入该单元的信息来配置单元:

let dataSource = RxCollectionViewSectionedReloadDataSource<SectionOfCustomData>(
    configureCell: { dataSource, collectionView, indexPath, item in
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as? SomeCell else { return UICollectionViewCell() }
        let output = cell.configure(with: item, initial: viewModel.cellStates.map { $0[item.id]! })
        output
            .bind(to: itemEdit)
            .disposed(by: cell.disposeBag)
        return cell
})