我有一个label
,isUserInteractionEnabled
设置为true
。现在,我需要为标签添加UITapGestureRecognizer
。有没有一种使用Rx
的方法来实现。
我查看了RxSwift库 这里。他们没有提供添加手势的扩展。UILabel+Rx
文件仅包含text
和attributedText
。
是否有任何解决办法来为标签添加手势?
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)
使用RxGesture库的Swift 5。
在我看来,这是最好、最简单的选择。
label
.rx
.tapGesture()
.when(.recognized) // This is important!
.subscribe(onNext: { [weak self] _ in
guard let self = self else { return }
self.doWhatYouNeedToDo()
})
.disposed(by: disposeBag)
注意! 如果您不使用 .when(.recognized)
,则轻拍手势将在标签初始化时立即触发!
使用 RxCocoa + RxSwift + RxGesture 的 Swift 4
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" })
}) )
})
作为George Quentin的写作,所有工作。
view.rx
.longPressGesture(configuration: { gestureRecognizer, delegate in
gestureRecognizer.numberOfTouchesRequired = 1
gestureRecognizer.numberOfTapsRequired = 0
gestureRecognizer.minimumPressDuration = 0.01
gestureRecognizer.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(":DEBUG:began")
case .changed:
print(":DEBUG:changed \(location)")
case .ended:
print(":DEBUG:end \(location)")
nextStep()
default:
break
}
})
.disposed(by: stepBag)
label
.rx
.tapGesture()
.subscribe(onNext: { _ in
print("tap")
}).disposed(by: disposeBag)
我在UI层简单地使用这个扩展来获取Driver
。
public extension Reactive where Base: RxGestureView {
func justTap() -> Driver<Void> {
return tapGesture()
.when(.recognized)
.map{ _ in }
.asDriver { _ in
return Driver.empty()
}
}
}
当我需要触发点击事件时,我调用这个函数
view.rx.justTap()
rx.event
而不是标签。我刚刚更新了答案。 - RvdB