Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

iPhone touchesEnded sometimes not called

I have a small game that needs to know when a user touches the screen and also when they release.

Now whilst I always get a touchesBegan event, sometimes I don't get the corresponding touchesEnded event (which is somewhat annoying).

Was just wondering if anyone else had seen this.

Posted on May 2, 2008 8:40 AM

Reply
22 replies

Jul 29, 2008 10:28 AM in response to AndyQua

Hello,

Yes I have also seen this and have yet to find a solution for it. In my app this happens for touchesEnded and touchedMoved events. It seems to be connected to the amount of touch events generated and also to the time spent in rendering. From my experience it seems to get worse if the device is running on battery power vs. power cable. I am trying to optimize my drawing routines for now, but never really got close to having all events delivered all the time.

Jul 29, 2008 3:23 PM in response to AndyQua

I guess i found kind of a remedy for this 🙂
my local docs were out of date

if I implement

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event


"dropped" touch events get handled there, no problem for "touchesEnded",
but still giving me a hard time doing "smooth moving" with many fingers

Message was edited by: hexler

Oct 25, 2008 9:39 PM in response to AndyQua

Same problem here.

I have NSLog debugging to console and clearly on occasion I get a touchesBegan without a touchesEnded or touchesCancelled. My application is primarily idle (10 Hz accelerometer calls) so it's not that I'm overwhelming the system.

This problem is even observable in the MoveMe sample application.

Where do the missing touch events go? It's pretty much impossible for me to recover the missing event, since from my application's perspective for all it knows there is a finger sitting there on the screen.

Anyone have a solution? 2.2? 🙂

Oct 25, 2008 11:10 PM in response to Jeff Mathews

I have a bit more information.

In my case the touchesEnded isn't getting lost, it's getting stuck in the event queue. The missing touchesEnded eventually makes an appearance upon a subsequent touch. Unfortunately that's not very useful. Unless I suppose, you're playing that Hold-On game where the object is to hold the button as long as possible without actually touching the screen in this case. 😉

Here is a Debugger Console log:

2008-10-25 23:41:12.570 app[2050:20b] touchesBegan
2008-10-25 23:41:12.594 app[2050:20b] touchesMoved
2008-10-25 23:41:12.662 app[2050:20b] touchesMoved
2008-10-25 23:41:12.691 app[2050:20b] touchesMoved
... AudioServicesPlaySystemSound
... CGAffineTransformScale
2008-10-25 23:41:12.873 app[2050:20b] soundEffectDoneCallback
...
... not touching. touchesEnded is missing.
...
... new touch started
2008-10-25 23:41:35.091 app[2050:20b] touchesBegan
2008-10-25 23:41:35.098 app[2050:20b] touchesEnded
2008-10-25 23:41:35.213 app[2050:20b] touchesEnded

Nov 3, 2008 9:57 AM in response to Jeff Mathews

Hi,

i have the same problem. I tested several scenarios and i think this could be a high bug in the touch handling. The end event is not fired when you tap very quick several times. Begin is fired, move is handled but end is not fired?

This is really bad for touch and animation purposes because my animation is handled in a separate thread and in the end event i like to animate - but this is not working and getting some errors if i am tapping to fast 😟

Any ideas to solve ?

Cheers
Ralf

Dec 18, 2008 7:49 AM in response to Scott Squires1

This bug is plaguing me too. I can tell you a simple way to reproduce this bug scenario like this:

Don't tap the screen with fingers. Instead, slide your whole palm across the screen (completely covering the screen) from one side to the other until you palm fall off the screen surface without lifting your hand at all, then your TouchEnded event is very likely to disappear.

Maybe i am crazy in doing this. But this does cause TouchEnded to disappear.
Try it in your code!

Message was edited by: shibq

May 23, 2009 1:25 PM in response to AndyQua

Hi, I've been wrestling with this problem for a few days now. I have something of a fix, which may help some of you, but it requires turning on the accelerometer.

First, it does seems as if the problem is that the timer events are crowding out touches and accelerometer events. But I've found a way to use the accelerometer update to avoid the problem.

Here is my workaround:

1. turn on the UIAccelerometer in your initialization code:

UIAccelerometer* theAccelerometer = [UIAccelerometer sharedAccelerometer];
theAccelerometer.delegate = self;

2. set the UIAccelerometer update interval to your desired frame rate:

theAccelerometer.updateInterval = .01667f;// ie, 60 fps

(For some reason — I am new to C — 1/60 doesn't seem to work, so I use floating decimals.)

3. Call your frame update method from within the UIAccelerometer update event:

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
[myView setNeedsDisplay];
}

The result is that myView should call drawRect as often as the UIAccelerometer updates. This may dip below your desired frame rate if things are too busy, but it seems to get as close to the rate you specify as possible. More importantly, it doesn't block touch events!

The downside, of course, is that you need to activate the accelerometer, which undoubtedly ***** up some resources (although I don't know how much.)

Anyway, I'd be curious to know if this works for anyone else.

Jun 5, 2009 2:37 PM in response to patricksmith

First of all I want to say that your post was both clever and potentially helpful.

I tried it and it was not successful. That is because the device must be moving all the time in order to generate the animations.

about the 1/60 problem. C language performs arithmetical operations according to the arguments. 1 and 60 are integers and therefore the operation is integer division (just like normal division but with doing round() at the end) which results in 0. if you want the compiler to perform float (normal) division, you should write 1/60.0 or 1.0/60 (1 float argument is enough).

Thanks again

Jun 12, 2009 3:26 PM in response to Insomniac1

Citing "Programming in Objective-C 2.0" by Stephen G. Kochan, "to explicitly express a float constant, append either f or F to the end of the number, like so: 12.5f".

I've followed this convention in all of my code, so you'd see the following implementation from me:
theAccelerometer.updateInterval = 1.0f/60.0f; // ie, 60 fps

Verbose, perhaps, but it's clear to the compiler and the code reviewer that floating point values are involved. Also, I have an aversion to mixing types (1/60.0) = (integer/float). Call me paranoid but leaving type conversion up to the compiler just makes me nervous, and as an admitted control freak I prefer to leave as little up to the compiler as possible.

Happy coding!

Message was edited by: jeffreyBeauchamp

Jun 13, 2009 6:30 PM in response to Insomniac1

Thanks for response, and thanks for clearing up my confusion about 1/60.

About your test... when I turn on the UIAccelerometer, I find that it sends events continuously, regardless of whether the device is moving. I'm not seeing any pauses in the animation, even when the device is completely still.

I'm developing (unusually, no doubt, at this point) on a 1st generation iPod Touch — maybe that accounts for your different results? I'd be curious to know if anyone has any luck implementing method this on a newer device.

Jun 13, 2009 6:39 PM in response to Insomniac1

Just to add a bit more...

According to the Apple dev page about the UIAccelerometer: "...updates are delivered regularly at the frequency you requested, whether or not the acceleration data actually changed."

(See 'Overview', here: http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIAccele rometer_Class/Reference/UIAccelerometer.html)

So, I'm pretty sure this should work across the board, although I wonder why it isn't working for you, Insomniac1. I found that I needed to have NO other timers running for the acceleration events to arrive regularly.

Sep 19, 2009 10:50 AM in response to AndyQua

Hi, having the same issue, yes, touchesEnded sometimes is not called if we tap too fast, but I am working on a solution which works for me:

as we get a UIEvent, we can read the UIEvent.timestamp property (we also get a timestamp on the UITouch reference), and ignore any second touch which goes too fast. We can also try to ignore if there is finally a touchesEnded event, saving an array of references of ignored touches.

Hope it can help anyone.

Jose.

iPhone touchesEnded sometimes not called

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple ID.