I've added two gesture recognizers to my UIView
:
func tap(sender: UITapGestureRecognizer){
if sender.state == .began {
print("snapping photo")
}
}
func longPress(sender: UILongPressGestureRecognizer) {
if sender.state == .began {
print("snapping video")
}
}
When both are set to state == .began
, only longPress
fires. When I set tap to .ended
, both fire.
Why doesn't tap work when its state is set to .began
?
The Handling UIKit Gestures tells us:
Gesture recognizers come in two types: discrete and continuous. A discrete gesture recognizer calls your action method exactly once after the gesture is recognized. After its initial recognition criteria are met, a continuous gesture recognizer performs calls your action method many times, notifying you whenever the information in the gesture’s event changes.
...
The
state
property of a gesture recognizer communicates the object’s current state of recognition. For continuous gestures, the gesture recognizer updates the value of this property from.began
to.changed
to.ended
, or to.cancelled
. Your action methods use this property to determine an appropriate course of action.
The UITapGestureRecognizer
is a discrete gesture, and as such, your event handler is called once when the gesture was recognized.
In practice, this means that your tap gesture recognizer handler will not be called for a state of .began
. It is, however, called for a state of .ended
.
(The Handling UIKit Gestures documentation tells us that the handler of a discrete gesture will be called “exactly once”. This is consistent with my experience. Confusingly, the tap gesture documentation and the Handling Tap Gestures reference suggest that one should test for a state of .ended
even though, in practice, that’s the only state for which your tap gesture handler will ever be called. Regardless, while it might be prudent to look for a state of .ended
, don’t ever expect to ever see a state of .began
in your discrete gesture handlers.)
The UILongPressGestureRecognizer
, on the other hand, is a continuous gesture, so checking the state is very useful (determining when the gesture .began
, .changed
, .ended
, etc.). That's why you see it called for the state
of .began
.