[英]How to detect double tap with RxSwift
我正在尝试使用 RxSwift 检测双击
如果没有 RxSwift,我会这样:
private func setupFakePanView() {
let singleTapGesture = UITapGestureRecognizer()
let doubleTapGesture = UITapGestureRecognizer()
singleTapGesture.numberOfTapsRequired = 1
doubleTapGesture.numberOfTapsRequired = 2
singleTapGesture.addTarget(self, action: #selector(self.tapped))
doubleTapGesture.addTarget(self, action: #selector(self.doubleTapped))
someView.addGestureRecognizer(singleTapGesture)
someView.addGestureRecognizer(doubleTapGesture)
singleTapGesture.require(toFail: doubleTapGesture)
}
@objc private func tapped() {
// Do something
}
@objc private func doubleTapped() {
// Do something else
}
有没有办法用 RxSwift、RxCocoa 和RxGesture实现同样的效果? 我已经尝试了以下但当然它不起作用:
someView.rx
.tapGesture(numberOfTouchesRequired: 1, numberOfTapsRequired: 1)
.when(.recognized)
.subscribe(onNext: { _ in
// Do something
})
.disposed(by: bag)
someView.rx
.tapGesture(numberOfTouchesRequired: 1, numberOfTapsRequired: 2)
.when(.recognized)
.subscribe(onNext: { _ in
// Do something else
})
.disposed(by: bag)
有没有办法让第一个 tapGesture 知道第二个必须失败?
我找到了 2 个解决方案来解决这个问题!
UITapGestureRecognizer
let doubleTapGesture = UITapGestureRecognizer()
doubleTapGesture.numberOfTapsRequired = 2
let singleTapGesture = UITapGestureRecognizer()
singleTapGesture.numberOfTapsRequired = 1
singleTapGesture.require(toFail: doubleTapGesture)
let singleTap = someView.rx
.gesture(singleTapGesture)
.when(.recognized)
.subscribe(onNext: { _ in
// Do something
})
.disposed(by: bag)
let doubleTap = someView.rx
.gesture(doubleTapGesture)
.when(.recognized)
.subscribe(onNext: { _ in
// Do something else
})
.disposed(by: bag)
要么..
UIGestureRecognizerDelegate
感谢Kishan建议Jegnux 的回答!
1 - 为单击手势设置自定义委托...
someView.rx
.tapGesture(
numberOfTouchesRequired: 1,
numberOfTapsRequired: 1,
configuration: { [weak self] gesture, delegate in
gesture.delegate = self
}
)
.subscribe(onNext: { _ in
// Do something
})
.disposed(by: bag)
// double tap same as before
2 - 实施gestureRecognizer(_:shouldRequireFailureOf:)
extension MyController: UIGestureRecognizerDelegate {
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
if let gesture = otherGestureRecognizer as? UITapGestureRecognizer, gesture.numberOfTapsRequired == 2 {
return true
}
return false
}
}
两种解决方案都可以正常工作。
此代码应该工作:
tap
.flatMapFirst {
tap
.takeUntil(tap.startWith(()).debounce(.milliseconds(300), scheduler: MainScheduler.instance))
.startWith(())
.reduce(0) { acc, _ in acc + 1 }
}
.map { min($0, 2) }
只需使用一个手势识别器(其事件称为tap
),它会在点击发生时立即发出。 map
上方的代码将此问题概括为 output 在这种情况下,彼此在特定时间段(300 毫秒)内连续点击的次数。 map只是为了保证只有一个1
或者一个2
出来。 然后随心所欲地执行任何条件逻辑。 我成功地用UIButton
测试了它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.