Reputation: 3435
I have a UIView
view, and I want to perform some action when user pressed it and then released.
I added a UITapGestureRecognizer
to the view, and it only fires when tap duration is small. If user touches the view, waits a couple of seconds and then lifts his finger, nothing happens. How can I detect "long tap" events?
UILongPressGestureRecognizer
does not work for me because it fires when finger still touches the screen.
Upvotes: 0
Views: 278
Reputation: 77423
You can do this by tracking when touchesBegan
and touchesEnded
:
class LongTapView: UIView {
var touchStart: Date!
var callback: ((Double)->())?
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
touchStart = Date()
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touchPoint = touches.first?.location(in: self),
self.bounds.contains(touchPoint) else {
// touch moved outside of self,
// so don't consider it "still pressed"
touchStart = Date.distantFuture
return
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touchPoint = touches.first?.location(in: self),
self.bounds.contains(touchPoint) else {
// touch was lifted outside of self
return
}
let seconds = -(touchStart.timeIntervalSinceNow)
if seconds < 0.0 {
// this will be the case if touchesMoved outside of self
// and then was dragged back in
return
}
// tell the controller how long the view was touched
callback?(seconds)
}
}
You can use it like this:
class TouchTestViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let v = LongTapView()
v.frame = CGRect(x: 80, y: 120, width: 150, height: 150)
v.backgroundColor = .red
view.addSubview(v)
v.callback = { elapsedTime in
// do what you want here, for example:
if elapsedTime > 4.0 {
print("View was pressed longer than 4 seconds!")
} else {
print("View was pressed for only \(elapsedTime) seconds")
}
}
}
}
Upvotes: 0