2

First of all sorry for the confusing title, but I actually can't come up with something better (if you do, please edit).

I have an application using Coordinator pattern and RxSwift, so all in all I wan to pass all navigation related stuff to Coordinator, so it can handle navigation logic.
In one view controller I have UITableView with cells which has UIButton inside of them. For that case I have a:

actionButton.rx.tap.bind(to: viewModel.chapterAction).disposed(by: disposeBag)

chapterAction is a PublishSubject<Void> as it only reflects a button tap, but I need to pass more info to Coordinator, so later I transform this chapterAction to:

var showChapter: Observable<Chapter> = self.chapterAction.mapTo(self.chapter)

And I assume that up to this point there's nothing wrong with this code, so in View Controller's .bind(to: tableView.rx.items... I have:

viewModel.showChapter.bind(to: self.viewModel.chapterAction).disposed(by: viewModel.disposeBag)

Since I want to bind this to view controller's viewModel and later subscribe in coordinator.
It all works ok, but for some cells I get duplicated taps, why? I've tried putting distinctUntil, shareReply, but nothing seems to help my problem and it's not a deterministic one. I suspect some reusing to be involved, but I have no clue where to start looking for this issue...

cojoj
  • 6,405
  • 4
  • 30
  • 52

2 Answers2

4

You need to re-initialize the disposeBag in prepareForReuse() method:

override func prepareForReuse() {
    super.prepareForReuse()
    disposeBag = DisposeBag()
}

Then, all previous subscriptions are disposed.

xandrefreire
  • 2,276
  • 14
  • 18
  • This isn’t the case - I’m doing this re-initialization, but still duplicates. Though, my code sample says I use dispose bag from viewModel I actually tried every dispose bag I had access from this place - cell’s, viewModel’s, view controller’s – cojoj Oct 24 '17 at 16:06
0

I still don't know exactly what was wrong with my code, but I ended up with adding mapTo directly in tableView.rx.items binding block. Now it looks like this:

viewModel.chapterCellViewModels
    .bind(to: tableView.rx.items(cellIdentifier: ChapterCell.nameOfClass, cellType: ChapterCell.self )) { (_, viewModel, cell) in
        cell.configureCell(with: viewModel)

        cell.actionButton.rx.tap
            .mapTo(viewModel.chapter)
            .bind(to: self.viewModel.chapterAction)
            .disposed(by: cell.disposeBag)
    }
    .disposed(by: disposeBag)

As I've mentioned in OP - I guess it was due to some reuse etc. but I'm not able to answer why this was happening.

cojoj
  • 6,405
  • 4
  • 30
  • 52