Rxswift: How to use rx_tap on UIButton of UITableViewCell

Created on 26 Nov 2015  路  8Comments  路  Source: ReactiveX/RxSwift

I have a similar question with https://github.com/ReactiveX/RxSwift/issues/248.
But I couldn't find answer above issue.

I'm trying to use rx_tap on a table view cell button.
after tapping button,then tableview reload,then rx_tap event happen without tapping.
Maybe i think subscribe is still cotinueing.

how can i prevent adding new rx_tap every time i reload the tableview?

import UIKit
#if !RX_NO_MODULE
import RxSwift
import RxCocoa
#endif

public protocol ConditionCellDelegate : class {

    func updateCell(atIndexPath: NSIndexPath,dic_pushcondition:NSDictionary)

}


@IBDesignable
class ConditionCell: ABMenuTableViewCell {


    ...
    @IBOutlet weak var cond_switch: OnOffBtn!
    weak var delegate:ConditionCellDelegate!


    var disposeBagCell:DisposeBag = DisposeBag()

    ....

    func setUpdateAction(atIndexPath:NSIndexPath,dic_pushcondition:NSDictionary){
        self.cond_switch.rx_tap
            .map{ [unowned self] _ in


               ....

                return send_param
            }
            .catchError{ error -> Observable<NSDictionary> in


                AppDelegate.sharedAppDelegate().showRxSwiftCommonMessage("鏇存柊銇с亶銇俱仜銈撱仹銇椼仧", message_type: TWMessageBarMessageType.Error, error: error)

                return empty()

            }
            .subscribeNext { [unowned self] send_param  in


                ....

            }.addDisposableTo(self.disposeBagCell)

    }




}
question

Most helpful comment

Hello @shiratsu, I think you simply must to create a new DisposeBag on each cell reuse

class TableViewCell: UITableViewCell {

    var disposeBagCell:DisposeBag = DisposeBag()

    ...

    override func prepareForReuse() {
        disposeBagCell = DisposeBag()
    }

}

All 8 comments

Hello @shiratsu, I think you simply must to create a new DisposeBag on each cell reuse

class TableViewCell: UITableViewCell {

    var disposeBagCell:DisposeBag = DisposeBag()

    ...

    override func prepareForReuse() {
        disposeBagCell = DisposeBag()
    }

}

Oh!That's simple.I will try it.Thank you!

馃槈

May I ask why you're assigning to disposeBagCell two times?

Hi, @charlag

Because life cycle of UITableViewCell ends on prepareForReuse so next time it will display another data, and you probably want to dispose previous subscriptions

I usually new up a cell's disposeBag in didEndDisplayingCell 馃檪

I assume then, that if you add some listening thing on the cell from the outside, you add the disposable back to it's disposeBag:

class TableViewCell: UITableViewCell {
    var disposeBag = DisposeBag()
    let subject = PublishSubject<Void>()

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

   @IBAction onSomeTableViewCellViewAction(_ sender: AnyObject){
        subject.onNext(())
    }
}

// then when you dequeue for reuse from the UITableViewDataSource
let item = tableView.dequeue...
item.subject
    .asObservable()
    .subscribe(onNext: {...})
    // put it in the items disposeBag so when it's reused it will be cleared
    .disposed(by: item.disposeBag)

I send ID in the subject but it gives some other ID only.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Z-JaDe picture Z-JaDe  路  3Comments

marlowcharite picture marlowcharite  路  3Comments

angerman picture angerman  路  3Comments

jeremiegirault picture jeremiegirault  路  3Comments

RafaelPlantard picture RafaelPlantard  路  3Comments