Touches Ended not being called

左心房为你撑大大i 提交于 2019-12-10 12:31:55

问题


I've playing around with recognizing the touches in an iOS Application, and I have this simple code

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
 NSLog(@"%lu",(unsigned long)[touches count]);
 [touches enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
     UITouch *touch = obj;
     CGPoint touchLocation = [touch locationInNode:self.scene];
     NSLog(@"B x:%f - y:%f",touchLocation.x,touchLocation.y);
 }];
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
 [touches enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
    UITouch *touch = obj;
    CGPoint touchLocation = [touch locationInNode:self.scene];
    NSLog(@"E x:%f - y:%f",touchLocation.x,touchLocation.y);
 }];
}

The touchesBegan is being called fine, if I place from 1 finger up to 5 fingers on the screen at the same time, I see it being called with the correct information

The same doesn't happen with touchesBegan, many time if I have 3 fingers on the screen and remove them simultaneously, I only see information on 2 touches being ended (and sometimes even 1). If I take the fingers out one at a time, the method also usually gets called 2 times (sometimes 1, although rarely it will be called the correct 3 times) As the number of touches increases, also the likely hood of some information not being shown in the touchesEnded method

Methods touchesMoved:withEvent: and touchesCancelled:withEvent: are also implemented, with the same logic

Can someone explain this behavior? Is there something I'm missing?


回答1:


You'd have to set recognizer.cancelsTouchesInView = false in Swift or recognizer.cancelsTouchesInView = NO; in Objective-C




回答2:


Try removing any Gesture Recognizers you have on that view. They can interfere with touchesEnded.




回答3:


You have to override all touch methods if you do not call super's implementation. So you have to also implement the touchesMoved:withEvent: and touchesCancelled:withEvent: methods. Implementations can be empty but you have to do it.

touchesBegan:withEvent:

If you override this method without calling super (a common use pattern), you must also override the other methods for handling touch events, if only as stub (empty) implementations.

Based on UIResponder Class Reference




回答4:


Try overriding the UIView's hitTest method:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
   return self;
}

It is possible that when you lift fingers they are not recognised as being in the UIView, sotouchesEnded is not called.




回答5:


  • Tap gestures (simple, long, 2xshort, 2xfingers tap) do not allow the calls Touches Ended / Canceled if cancelsTouchesInView == NO
  • They allow its calling ONLY IF cancelsTouchesInView property is the default YES
  • Pinch gesture allows all the calls (to Touches Begin / Moved / Ended / Canceled) ONLY IF cancelsTouchesInView property is set to NO
  • If for the pinch gesture the cancelsTouchesInView property would have been YES, touchesMoved would not have been called

Inside info:

I am using:

  • 1 finger UITapGestureRecognizer
  • 1 finger UILongPressGestureRecognizer
  • 1 finger double tap UITapGestureRecognizer
  • 2 fingers tap UITapGestureRecognizer
  • 1 UIPinchGestureRecognizer

And also should receive one finger panning. But what i have found out is that the Pinch gesture was not Ending even if the user had risen one finger. Somehow iOS is still calling the Pinch's selector with "Changed" state.

My solution was to use the touchesBegin/Moved/Ended to catch the pan and use the number of active touches as safety check in case the pinch selector would be called.

Other settings i had to use in making the above configuration:

self.multipleTouchEnabled = YES;
[oneFingerTapRecognizer requireGestureRecognizerToFail:oneFingerLongPressRecognizer];
[oneFingerTapRecognizer requireGestureRecognizerToFail:oneFingerDoubleTapRecognizer];
[oneFingerLongPressRecognizer requireGestureRecognizerToFail:oneFingerDoubleTapRecognizer];
[twoFingersTapRecognizer requireGestureRecognizerToFail:twoFingersPinch];



回答6:


I had the same problem and solved it with this simple code in the touches ended:

NSInteger touchCount = 0;
for (UITouch *touch in touches) {
   touchCount++;
    if([[event allTouches]count] == touchCount){
       // do what you have to do here
    }
}

// You will get a warning here but don't care about it

I hope this help!




回答7:


I had the same problem, even after defining all four touch handlers. I also didn't have any active recognizers.

The solution for me was to simply enable multi touch events on my view, like so

self.multipleTouchEnabled = YES;

which magically solved the problem.

Note that I did get "multi touch" events even before this, i.e. events for multiple fingers at the same time, but I had the above issue that not all of them were ended properly.

Hope that helps someone! :)



来源:https://stackoverflow.com/questions/22127451/touches-ended-not-being-called

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!