Reputation: 11
I want to detect the state similar to "touchesBegan" and "touchesEnded" on watchOS by using WKTapGestureRecognizer. But following codes always return state no.3 (touches ended).
- (IBAction)handleGesture:(WKTapGestureRecognizer*)gestureRecognizer{
NSLog(@":%ld",(long)gestureRecognizer.state);}
Could you tell me how to detect state no.1 and no.2.
Upvotes: 1
Views: 932
Reputation: 623
As stated in the official documentation, WKTapGestureRecognizer is a discrete gesture recognizer, meaning that it will trigger its event only when it finishes to recognize it i.e. after the user quickly taps and then raises his finger.
To receive multiple state changes from a recognizer you must use a continuous recognizer such as WKLongPressGestureRecognizer (PanGesture doesn't quite do the trick): if you set a very low minimumPressDuration
value - 0.1 seconds for example - you can trick it to behave similarly to a tap recognizer, like so:
@IBAction func onRecognizerStateChange(_ recognizer: WKLongTapGestureRecognizer) {
switch recognizer.state {
case .began:
print("User just touched the screen, finger is still resting")
case .ended:
print("User has raised his finger")
default:
break
}
}
Keep in mind that regardless of the allowableMovement
property value, after the recognizer transitions to the Begin state, the user is still allowed to drag his finger around, which might not be desirable if you're trying to detect a simple tap. To overcome this, you can store the initial touch location when the recognizer switches to the Begin state and then check if the touch travels too far at each Changed state callback, like in the following example:
private var touchLocation = CGPoint.zero
@IBAction func onRecognizerStateChange(_ recognizer: WKLongTapGestureRecognizer) {
switch recognizer.state {
case .began:
touchLocation = recognizer.locationInObject()
print("User just touched the screen at \(touchLocation)")
case .changed:
let location = recognizer.locationInObject()
let distance = sqrt(pow(touchLocation.x - location.x, 2.0)
+ pow(touchLocation.y - location.y, 2.0))
if distance >= 10 {
print("User traveled too far from \(touchLocation)")
// invalidate the gesture recognizer
recognizer.isEnabled = false
recognizer.isEnabled = true
}
case .ended:
print("User successfully completed a tap-like gesture")
default:
break
}
}
Upvotes: 2