RxSwift: How to add gesture to UILabel? RxSwift: How to add gesture to UILabel? ios ios

RxSwift: How to add gesture to UILabel?


A UILabel is not configured with a tap gesture recognizer out of the box, that's why RxCocoa does not provide the means to listen to a gesture directly on the label. You will have to add the gesture recognizer yourself. Then you can use Rx to observe events from the recognizer, like so:

let disposeBag = DisposeBag()let label = UILabel()label.text = "Hello World!"let tapGesture = UITapGestureRecognizer()label.addGestureRecognizer(tapGesture)tapGesture.rx.event.bind(onNext: { recognizer in    print("touches: \(recognizer.numberOfTouches)") //or whatever you like}).disposed(by: disposeBag)


Swift 5 (using RxGesture library).

Best and simplest option imho.

     label        .rx        .tapGesture()        .when(.recognized) // This is important!        .subscribe(onNext: { [weak self] _ in            guard let self = self else { return }            self.doWhatYouNeedToDo()        })        .disposed(by: disposeBag)

Take care! If you don't use .when(.recognized) the tap gesture will fire as soon as your label is initialised!


Swift 4 with RxCocoa + RxSwift + RxGesture

let disposeBag = DisposeBag()let myView = UIView()myView.rx  .longPressGesture(numberOfTouchesRequired: 1,                    numberOfTapsRequired: 0,                    minimumPressDuration: 0.01,                    allowableMovement: 1.0)            .when(.began, .changed, .ended)            .subscribe(onNext: { pan in                let view = pan.view                let location = pan.location(in: view)                switch pan.state {                case .began:                    print("began")                case .changed:                    print("changed \(location)")                case .ended:                    print("ended")                default:                    break                }            }).disposed(by bag)

or

myView.rx.gesture(.tap(), .pan(), .swipe([.up, .down])).subscribe({ onNext: gesture in    switch gesture {    case .tap: // Do something    case .pan: // Do something    case .swipeUp: // Do something     default: break           }        }).disposed(by: bag)

or event clever, to return an event. i.e string

var buttons: Observable<[UIButton]>!let stringEvents = buttons        .flatMapLatest({ Observable.merge($0.map({ button in            return button.rx.tapGesture().when(.recognized)                .map({ _ in return "tap" })            }) )        })