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.
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
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?
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
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
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 ?
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
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
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.
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).
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.
Message was edited by: jeffreyBeauchamp
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.
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.