RxSwift: Как добавить жест в UILabel?

У меня есть label с isUserInteractionEnabled установленной в true. Теперь мне нужно добавить UITapGestureRecognizer для метки. Есть ли способ добавить в Rx способ.

Я посмотрел библиотеку RxSwift здесь. Который они не предоставили никакого расширения для добавления жеста. UILabel+Rx имеет только text и attributedText text.

Есть ли обходной путь, чтобы добавить жест на ярлык?

Ответ 1

UILabel не настроен с помощью распознавателя жестов, из-за чего RxCocoa не предоставляет средства для прослушивания жестов непосредственно на ярлыке. Вам придется добавить распознаватель жестов самостоятельно. Затем вы можете использовать Rx для наблюдения за событиями из распознавателя, например:

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)

Ответ 2

Swift 4 с 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)

или же

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)

или событие умное, чтобы вернуть событие. т.е. строка

var buttons: Observable<[UIButton]>!

let stringEvents = buttons
        .flatMapLatest({ Observable.merge($0.map({ button in
            return button.rx.tapGesture().when(.recognized)
                .map({ _ in return "tap" })
            }) )
        })

Ответ 3

Эти расширения являются технически частью библиотеки RxCocoa, которая в настоящее время упакована вместе с RxSwift.

Вы должны иметь возможность добавить UITapGestureRecognizer к представлению, а затем просто использовать rx.event(rx_event, если старше) на этом объекте жестов.

Если вам нужно сделать это в контексте UILabel, вам может понадобиться также обернуть его внутри UILabel + Rx, но если у вас есть более простые требования, просто использование rx.event на жесте должно быть хорошим обходным решением.

Ответ 4

Вы можете подписать ярлык на жест касания

    label
        .rx
        .tapGesture()
        .subscribe(onNext: { _ in
            print("tap")
        }).disposed(by: disposeBag)