Reputation: 622
I want to get a callback when my UIPinchGestureRecognizer finished a pinch-gesture. Moreover it would be great to know if the finished gesture was a zoom in or a zoom out.
Does anyone know a method to use? Or the approach to do?
Thanks!
Upvotes: 10
Views: 3433
Reputation: 3660
For some reason, I am not consistently receiving a pinch gesture recognizer state of .ended
when testing on my devices. I've managed to get this to trigger once in awhile, but it is wildly inconsistent.
(I wonder if it is because I have a pinch gesture recognizer attached to a UICollectionView
, but I haven't tried it with other views to confirm. For this reason, I don't think overriding touchesEnded
is a solution that I can consider since other touch events/gestures are being used.)
The most consistent check I could perform was to confirm the number of touches on the gesture recognizer.
Assuming you have attached a pinch gesture recognizer to a view:
let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(didReceivePinchGesture))
yourView.addGestureRecognizer(pinchGesture)
Inside the handler, I check the number of touches to ensure that it is a pinch gesture. If it is not two, then I can deduce that this is the end of the gesture:
@objc func didReceivePinchGesture(_ gestureRecognizer: UIPinchGestureRecognizer) {
guard gestureRecognizer.numberOfTouches == 2 else {
// Logic for pinch gesture ended
return
}
if gestureRecognizer.state == .began {
...
} else if gestureRecognizer.state == .changed {
...
} else {
// Same logic for pinch gesture ended (though rarely invoked)
}
}
Caveat: When testing this, similar to how the .ended
state does not get triggered if you don't lift your fingers at exactly the same millisecond, it appears as though the gesture recognizer is called even when there's only one touch at the beginning if your fingers do not touch the screen at the exact same time.
I have explicit logic to begin processing the gesture when the state equals .began
so this didn't have any negative impacts on my logic. However, depending on what you are trying to accomplish this may be a concern for you.
Upvotes: 0
Reputation: 556
The best approach which does not require subclassing is to examine the "state" property on the gesture recognized instance in your action handler. The state will change during all phases of the lifecycle of the gesture. The state change you're looking for is UIGestureRecognizerStateEnded. It is also good practice to check for UIGestureRecognizerStateCancelled as well.
Upvotes: 0
Reputation: 1069
Another approach instead of overriding touchesEnded:, is that you could just check the state of the gesture recognizer in your target handler method.
-(void)handlePinchGesture:(UIGestureRecognizer*)gestureRecognizer {
if(UIGestureRecognizerStateEnded == [gestureRecognizer state]){
// do something
}
}
Upvotes: 14
Reputation: 2092
You can know if it was a zoom in or out by the scale property of the UIPinchGestureRecognizer.
Just overrride it's touchesEnded: method to get a callback (and the call some other method if you wish).
Upvotes: 1