简体   繁体   中英

How do I trigger action for rx.tap.bind of UIButton?

I simply have something like this:

    class CheckboxView: UIView {
        private let button = UIButton()
        var rxaction: RxSwift.Reactive<UIButton> {
            button.rx
        }
    }

    let view = CheckboxView()

    view.rxaction.tap.bind { in
          print(sth)
    }.disposed(by: disposeBag)

How can I perform action manually using rxaction to call bind closure?

The essence of functional reactive programming is to specify the dynamic behavior of a value completely at the time of declaration. -- Heinrich Apfelmus

So by wanting to perform an action manually, you aren't using FRP properly. That said, the transition to an FRP mindset can be tough.

When you want to deal with an Observable in an imperative manor, you need a Subject. In your case, the goal is to emit an event either when the button is tapped or imperatively. So you do that like this:

class CheckboxView: UIView {
    private let button = UIButton()
    private let _manualAction = PublishSubject<Void>()

    let tap: Observable<Void>

    override init(frame: CGRect) {
        tap = Observable.merge(
            button.rx.tap.asObservable(),
            _manualAction
        )
        super.init(frame: frame)
    }

    required init?(coder: NSCoder) {
        tap = Observable.merge(
            button.rx.tap.asObservable(),
            _manualAction
        )
        super.init(coder: coder)
    }

    deinit {
        _manualAction.onCompleted()
    }

    func actManually() {
        _manualAction.onNext(())
    }
}

Note that tap is a let not a var this is because if you make it a var it might get replaced which will not unseat any subscribers. They would continue to point to the previous object and force it to stay alive.

Also notice that I'm not using a computed property. That's because doing so would create a different Observable every time tap is called. In general that's not what you want so you should make it a habit to avoid it. (In this particular case, the result is a hot Observable so it would be okay to do, but if you routinely do it, you will be wrong much of the time.)

Lastly, you may be wondering why you have to go through all this just to manually trigger the subscription. Again, remember that manual triggers go against the essence of what FRP is all about. You should avoid it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM