如何避免使用RxDataSources重复点击Tableview上的按钮

时间:2019-01-02 13:21:44

标签: ios swift uitableview rx-swift rxdatasources

我有一个带有RxDataSources的表视图,在该视图上单元格项目具有一个删除图标。当单元出列并单击该删除图标时,所有先前的单击事件都将被触发,从而重复点击。 物品格:

 removeImageView.rx.tap().map { _ in indexPath } 
            .bind(to: viewModel.onRemoveItem).disposed(by: cellDisposeBag)

单元格视图模型:

let onRemoveItem = PublishSubject<IndexPath>()

绑定单元格和ViewModel的视图控制器视图模型:

 let vm = ItemViewModel(with: item)
            vm.onRemoveItem.bind(to: self.onRemoveItem).disposed(by: self.rx.disposeBag)

            return SectionItem.item(viewModel: vm)

视图控制器:

let dataSource = RxTableViewSectionedReloadDataSource<SectionItem>(configureCell: { dataSource, tableView, indexPath, item in
    switch item {
    case .item(let viewModel):
        let cell = (tableView.dequeueReusableCell(withIdentifier: itemtIdentifier, for: indexPath) as? ItemCell)!
        cell.bind(to: viewModel, at: indexPath)
        return cell
    }
}, titleForHeaderInSection: { dataSource, index in
    let section = dataSource[index]
    return section.title
}  )

output?.items
    .bind(to: tableView.rx.items(dataSource: dataSource))
    .disposed(by: rx.disposeBag)

output?.onRemoveCartIemTapped.distinctUntilChanged() 
    .skip(1)
    .distinctUntilChanged().drive(onNext: { [weak self] (indexPath) in
    print("onRemoveCartIemTapped" + String(indexPath.item))
}).disposed(by: rx.disposeBag)

控制台调试:

onRemoveCartIemTapped0
onRemoveCartIemTapped3
onRemoveCartIemTapped1
onRemoveCartIemTapped4

1 个答案:

答案 0 :(得分:1)

这是由于UITableView重用单元格引起的。为了避免有多个订阅,您可以覆盖单元格的prepareForReuse()方法,并确保处置所有现有的订阅。

我通常将DisposeBag声明为var,然后在DisposeBag中为其分配一个新的prepareForReuse()。取消DisposeBag时,它将处置它包含的所有预订。像这样:

override func prepareForReuse() {
    super.prepareForReuse()

    cellDisposeBag = DisposeBag()
}