简体   繁体   中英

How to get which button is clicked in RxSwift

I have created a common action for an array of my button. I just want to get the which button is tapped.

I have array of buttons like let buttons = [UIButton(), UIButton(), UIButton(),UIButton()] .

let observable = Observable.of(buttons[0].rx.tap, buttons[1].rx.tap, buttons[2].rx.tap, buttons[3].rx.tap).merge()
    observable.subscribe(onNext: {
      print("I want to find which button is tapped.")
    }).disposed(by: disposeBag)

You are using merge(). You can't know which on is being tapped.

If you want multiple buttons but one action you are doing the right thing.

let observable = Observable.of(buttons[0].rx.tap, buttons[1].rx.tap, 
    buttons[2].rx.tap, buttons[3].rx.tap).merge()
    observable.subscribe(onNext: {
    print("I want to find which button is tapped.")
    }).disposed(by: disposeBag)

If the action is different then: Example Let's say I have a UIView and 4 buttons. In button tap, you change the background of the view. Different color per button. So same function but different color.

Observable.of(UIButton().rx.tap.map { _ in UIColor.red }).merge().subscribe(onNext: { color in
       UIView().backgroundColor = color
   })

Just map the tap events to some custom IDs -

let observable = Observable.merge(
  buttons[0].rx.tap.map { 0 },
  buttons[1].rx.tap.map { 1 },
  // etc.
)

observable.subscribe(onNext: { id in
  print("\(id) button is tapped.")
}).disposed(by: disposeBag)

The correct answer is to not merge the buttons in the first place. If you want to do four different things, then have four different observables. If they are all doing the same thing, just with different data then simply:

let taps = buttons.enumerated().map { ($0.0, $0.1.rx.tap) }
let toInts = taps.map { index, obs in obs.map { index } }
let mergedTaps = Observable.merge(toInts)

On review, I really like an answer by @Sooraj_snr that has been deleted. Use the buttons' tags instead of their position in the array. It's much more robust.

let tags = buttons
    .map { ($0.rx.tap, $0.tag) }
    .map { obs, tag in obs.map { tag } }
let values = Observable.merge(tags)

Here we give the button tag.

buttons.enumerated().forEach { (index, button) in
  button.tag = index
}

Here we got the which button we have selected.

for button in buttons {
  button.rx.tap.subscribe { [weak self] event in
    print("Selected Button :- \(button.tag)")
    }.disposed(by: disposeBag)
}

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