我正在尝试使用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知道第二个必须失败?
您可以使用RxGesture(https://github.com/RxSwiftCommunity/RxGesture)。
并且用法就像您写的一样:
clapButton.rx.
.tapGesture(numberOfTapsRequired: 2)
.when(.recognized)
.subscribe(onNext: {
// toggle the light
})
我已经找到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
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
上方的代码将这个问题推广为在彼此的特定时间段(300毫秒)内输出连续抽头的数量。该映射只是为了确保仅出现1
或2
。然后使用您喜欢的任何条件逻辑。我成功地用UIButton
对其进行了测试。