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" }) }) ) })