Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subscription to a UIButton.rx.tap located in UITableViewCell within UITableViewDataSource

Let's say I have a UIButton in a UITableViewCell. After dequeuing the cell from the UITableView I want to subscribe to the UIButton.rx.tap. The issue is that if my UITableViewCell is dequeued multiple times, the subscriptions would retain. Currently I solve this problem by allocating a Disposable property in my UITableViewCell, setting it when the subscription is create, and calling Disposable.dispose() on UITableViewCell.prepareForReuse(), however as far as I understand implementing features in a way that requires you to call Disposable.dispose() implies that you are doing something wrong.

Is there any better way to accomplish uniqueness of the subscription without reallocating UIButton?

like image 908
Timofey Solonin Avatar asked Dec 08 '22 20:12

Timofey Solonin


2 Answers

Another solution (which doesn't require an additional library or calling Disposable.dispose()) is to have a DisposeBag in the cell and re-create it in prepareForReuse, as suggested in this GitHub issue:

//in the cell 

private(set) var disposeBag = DisposeBag()

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


//in the data source
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! DiaryItemCell

cell.commentButton.rx_tap
            .subscribeNext{

            }.addDisposableTo(cell.disposeBag)

return cell

It will also work if you have more buttons (or other Observables which you want to subscribe to) in your cell. You won't have to create a new Disposable in the cell itself for each of them.

like image 137
Michał Ciuba Avatar answered Dec 28 '22 08:12

Michał Ciuba


You can use Cell-Rx pod form correct using reactive subscriptions in UITableViewCell. For your case you can use rx_reusableDisposeBag, it will dispose your subscriptions correct.

like image 34
Artem Novichkov Avatar answered Dec 28 '22 08:12

Artem Novichkov