Как избежать двойного нажатия на кнопку в табличном представлении с RxDataSources - PullRequest
0 голосов
/ 02 января 2019

У меня есть табличное представление с 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 голосов
/ 03 января 2019

Это вызвано UITableView повторным использованием ячейки.Чтобы избежать нескольких подписок, вы можете переопределить метод ячейки prepareForReuse() и убедиться, что все существующие подписки удалены.

Обычно я объявляю DisposeBag как переменную, а затем присваиваю ей новую DisposeBag вprepareForReuse().Когда DisposeBag деинициализирован, он удалит все подписки, которые он содержит.Что-то вроде:

override func prepareForReuse() {
    super.prepareForReuse()

    cellDisposeBag = DisposeBag()
}
...