Search code examples
iosuibuttonrx-swiftreactivexrxdatasources

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?


Solution

  • 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.