The default -(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event works according to the following principle:

  1. Touching the screen with your first finger
  2. Triggers "touchesBegan" 1
  3. Press the screen with the second finger
  4. Triggered "touchesBegan" 2
  5. Let go of the first finger
  6. Nothing works
  7. Let go of the second finger
  8. Triggered "touchesEnded" 1
  9. Triggered "touchesEnded" 2

But how to make it work like this:

  1. Touching the screen with your first finger
  2. Triggers "touchesBegan" 1
  3. Press the screen with the second finger
  4. Triggered "touchesBegan" 2
  5. Let go of the first finger
  6. Triggered "touchesEnded" 1
  7. Let go of the second finger
  8. Triggered "touchesEnded" 2
  • multipleTouchEnabled enabled? - Max Mikheyenko
  • @MaxMikheyenko yes, ".multipleTouchEnabled = true" stands wherever possible, does not help. As such, multitouch works, but it is precisely "touchesEnded" that works only when the last touch is removed. - xXxxX
  • touchended will not be called, because the touch is still active. In touchmoved, you most likely need to look at how many tachets there are, compare with the saved value, and if the number of tachets is less, then do what you need - Max Mikheyenko

1 answer 1

Update the answer to clarify how multicasting works. your caption is incorrectly written - the correct order of handling touches is the following: all touches have a beginning and an end, an address that can be attached to a variable, all touches are entered into an array of touches touch to their variables.

The touchesEnded function starts always at the end of any touch, and the touchesBegan function starts. always starts at the beginning of the next touch.

declare variables UITouch * touch1; UITouch * touch2;

 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { NSLog(@"began start"); //перебираем касания for (UITouch *touch in touches) { if (touch1 == nil) { NSLog(@"touch1 began"); touch1 = touch; } else if (touch2 == nil) { NSLog(@"touch2 began"); touch2 = touch; } } } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { for (UITouch *touch in touches) { if (touch == touch1) { NSLog(@"moved1"); } else if (touch == touch2) { NSLog(@"moved2"); } } } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { for (UITouch *touch in touches) { if (touch == touch1) { touch1 = nil; NSLog(@"ended1"); } else if (touch == touch2) { touch2 = nil; NSLog(@"ended2"); } } } 

output result

began start

touch1 began first finger

began start

touch2 began second finger

moved1

moved1

moved2

ended1 let go first

moved2

ended2 let go of the second

  • It does not work, touchesEnded is called only after you release all the fingers, and then ended1 goes out and ended2. When you release the first finger touchesEnded does not work. - xXxxX
  • I found such a way for touchesBegan, maybe it’s worth digging in this direction, but I don’t know how to convey this to touchesEnded, maybe you can tell if this is possible. stackoverflow.com/questions/15628133/… - xXxxX
  • Well, from the log I moved2 - the finger moved after the touchesEnded was triggered. In general, it should work - I have a ping-pong toy for two players, it works) all touches have a beginning and an end, you just have to keep track of which touch when it ends. if you don't figure it out, throw off the code, I'll check it out - Rapax
  • no need to dig anywhere - my code is working, I launched it and copied it here with the log - Rapax
  • touchesEnded completely copied? here the editor does not contain all the code, scroll through to the end - Rapax