This issue I think deserves its own question. Using the code attached to my solution to another problem I discovered the issue described here.
I have the main view controller set as a UIGestureRecognizerDelegate, and I implement touchesBegan, touchesMoved, touchesEnded, and touchesCancelled programming my solution with the assumption that for every touch object with a touchesBegan event there would be a touchesEnded or touchesCancelled event for that same object. I’m finding that not to be the case, though.
Scenario:
The following events happen in this order.
-
User starts gesture 1, touching the screen and sliding the finger.
-
User starts gesture 2, touching the screen at a different location.
-
User continues to slide both fingers at their respective parts of the screen.
-
User lifts finger off the screen for gesture 2.
-
User continues gesture 1.
-
User lifts finger off the screen for gesture 1.
Using NSLog to capture the details of the touch event, I find that a separate touch object is used for gesture 1 and gesture 2. But while touchesBegan, touchesMoved, and touchesEnded are all called for gesture 1, only touchesBegan and touchesMoved are called for gesture 2. The event touchesCancelled is not called for it either.
So how can I tell when gesture 2 finishes if touchesEnded and touchesCancelled are not called?
Edit: I found another post with similar symptoms. Most of my subviews are created programmatically, though. I’ll try what was suggested there for the others. I’m skeptical it is the same issue, though, since in my testing, the touch locations are not anywhere near the other views.
Another edit: Following the recommendation in the link posted in my previous edit, I looked at the subviews, and one had user interaction checked. After I unchecked it, the behavior is slightly different. Now the second touch isn’t noted at all in any of the touch events. I must be missing something basic. The main view, and the view with user interaction checked, by the way, both occupy the same space (one encapsulates the other).
My original assumption that each touch would have its own object that starts at
touchesBeganand ends with eithertouchesEndedortouchesCancelledI think is correct. It is with my current implementation anyway. I originally wasn’t seeing a second touch because Multiple Touch was not enabled for the view I was working with. I enabled that, per suggestion in the comments. After that, I was able to see some, but not all touch events for the second touch. The reason I was sometimes not seeing the second touch was because I had a subview that had user interaction enabled. Apparently, it was commandeering the touches. I unchecked that and then was able to see the touch objects.I then switched tracking the touches by coordinates to touch IDs and was able to track the complete lifespan of all touches. Tracking by coordinates didn’t work because I found that for the second touch, the
touchesEndedcoordinates were identical to the last one intouchesMovedrather than the previous location intouchesEndedmatching the touchLocation intouchesMovedas with the first touch. If this sounds confusing, just track the touches by touch ID instead of by coordinates.