在我最初的答案中,我回答了如何让按钮同时识别点击和长按的问题。在澄清的问题中,只要用户按住手指,您似乎希望此按钮持续“触发”。如果是这种情况,只需要一个手势识别器。
例如,在 Interface Builder 中,将对象库中的长按手势识别器拖到按钮上,然后将“Min Duration”设置为零:
然后您可以控制-从长按手势识别器拖动到助手编辑器中的代码并添加@IBAction来处理长按:
weak var timer: Timer?
@IBAction func handleLongPress(_ gesture: UILongPressGestureRecognizer) {
if gesture.state == .began {
timer?.invalidate()
timer = Timer.scheduledTimer(withTimeInterval: 0.3, repeats: true) { [weak self] timer in
guard let self = self else {
timer.invalidate()
return
}
self.handleTimer(timer)
}
} else if gesture.state == .ended || gesture.state == .cancelled {
timer?.invalidate()
}
}
func handleTimer(_ timer: Timer) {
print("bang")
}
或者,如果您还想在用户将手指从按钮上移开时停止触发,请添加对手势位置的检查:
@IBAction func handleLongPress(_ gesture: UILongPressGestureRecognizer) {
if gesture.state == .began {
timer?.invalidate()
timer = Timer.scheduledTimer(withTimeInterval: 0.3, repeats: true) { [weak self] timer in
guard let self = self else {
timer.invalidate()
return
}
self.handleTimer(timer)
}
} else if gesture.state == .ended || gesture.state == .cancelled || (gesture.state == .changed && !gesture.view!.bounds.contains(gesture.location(in: gesture.view))) {
timer?.invalidate()
}
}
下面是我的原始答案,即如何识别按钮上的点击和长按的不同问题:
就个人而言,我会使用点击和长按手势识别器,例如:
override func viewDidLoad() {
super.viewDidLoad()
let longPress = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(_:)))
button.addGestureRecognizer(longPress)
let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
tap.shouldRequireFailure(of: longPress)
button.addGestureRecognizer(tap)
}
@objc func handleTap(_ gesture: UITapGestureRecognizer) {
print("tap")
}
@objc func handleLongPress(_ gesture: UILongPressGestureRecognizer) {
if gesture.state == .Began {
print("long press")
}
}
如果您愿意,也可以通过长按手势对.Ended 执行您的操作。这仅取决于所需的用户体验。
仅供参考,您也可以直接在 Interface Builder 中添加这两个手势识别器(只需将相应的手势从对象库拖到按钮上,然后从手势识别器中 control-drag到@IBAction 函数),但通过以编程方式显示它更容易说明正在发生的事情。