iosswiftuiviewuigesturerecognizeruievent

When do "finger" events get sent as Gestures to UIGestureRecognizer vs touchesBegan/touchesMoved/touchesEnded to UIView


I come from macOS/Cocoa & Mouse Events, and I'm trying to get a hang of these "Finger"(my own name for it) events


My question is:

When a "Finger" event is happening on a UIView (let's call MyView), when does it get sent as a Gesture to a UIGestureRecognizer on MyView, and when does it get sent as a touchesBegan/touchesMoved/touchesEnded to MyView


I have searched with all possible queries I could think of, and really only found a few decent sources, but nothing that answers exactly what I'm looking for

touchesBegan, touchesEnded, touchesMoved for moving UIView

UIGestureRecognizers vs touchesBegan/touchesMoved/touchesEnded (accuracy)

My best guess right now is that the difference between touchBegan/touchMoved/touchEnded and a Gesture recognizer depends on the speed of the finger?

So if you tap, and slowly move, the underlying UIView receives the touchMoved events. If you Tap and drag quickly, a gesture is created and passed to the the GestureRecognizer of the underlying UIView

My current guess is that when the finger touches down, event runloop detects this finger, and fires a touchesBegan. As you move your finger around, it fires touchesMoved.
However, if you are moving quickly enough, or in a way that the runtime thinks that you're making a gesture, it instead creates a Gesture and fires a message to the UIGestureRecognizer, instead of sending touchesMoved

I am currently trying to test out this hypothesis, but it's pretty tedious and I don't have a really good sample project to test with, so I figured I'd crowdsource some insight if possible. I'll report back if I figure it out myself as well


Solution

  • It's complicated (or can be), but the basic rule is simple. [For additional details, see my book.]

    A finger is a UITouch which is wrapped in a UIEvent for delivery. Delivery proceeds touches began, touches moved, touches moved ... touches ended / cancelled at which point that finger is no longer there.

    As a touch (finger) appears, the initial UITouch / UIEvent (touches began) is sent to both the view and its gesture recognizer(s) and any gesture recognizers higher up the view hierarchy. That way, touches are delivered to the view as normal, and at the same the gesture recognizers can be thinking about the gesture.

    That keeps happening repeatedly (touches moved) until either the touch is lifted (touches ended) or one of the gesture recognizers recognizes. In the latter case, all the other g.r.s are forced to fail, the touch is cancelled to the view, and only the recognizing g.r. gets the rest of the touches as they proceed.