在我最初的答案中,我回答了如何让按钮同时识别轻按和长按的问题。在澄清的问题中,只要用户按住手指,您似乎希望此按钮持续“触发”。如果是这种情况,则只需要一个手势识别器。
例如,在 Interface Builder 中,将对象库中的长按手势识别器拖到按钮上,然后将“Min Duration”设置为零:

然后,您可以control从长按手势识别器 - 拖动到助手编辑器中的代码并添加一个@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从手势识别器拖到@IBAction
函数),但更容易说明发生了什么通过以编程方式显示它。