views:

2210

answers:

3

When you drag a finger across the iPhone touchscreen, it generates touchesMoved events at a nice, regular 60Hz.

However, the transition from the initial touchesBegan event to the first touchesMoved is less obvious: sometimes the device waits a while.

What's it waiting for? Larger time/distance deltas? More touches to lump into the event?

Does anybody know?

Importantly, this delay does not happen with subsequent fingers, which puts the first touch at a distinct disadvantage. It's very asymmetric and bad news for apps that demand precise input, like games and musical instruments.

To see this bug/phenomenon in action

  1. slowly drag the iPhone screen unlock slider to the right. note the sudden jump & note how it doesn't occur if you have another finger resting anywhere else on the screen

  2. try "creeping" across a narrow bridge in any number of 3D games. Frustrating!

  3. try a dual virtual joystick game & note that the effect is mitigated because you're obliged to never end either of the touches which amortizes the unpleasantness.

Should've logged this as a bug 8 months ago.

A: 

Its waiting for the first move. That's how the OS distinguishes a drag from a tap. Once you drag, all new notifications are touchesMoved.

This is also the reason why you should write code to execute on touch up event.

Ajay Gautam
I'm curious about what constitutes a "first move". Your point "all new notifications are touchesMoved after a drag" is wrong: if you tap with a different finger, you of course get a touchesBegan event. However these further touches seem to transition much quicker to touchesMoved events. Curious. Re: the "touch up" event advice, I'm implementing something a bit more tactile than your average button or checkbox, so that won't cut it.
Rhythmic Fistman
I can confirm this. It's a really big problem in iPhone OS.
Thanks
+1  A: 

After a touchesBegan event is fired the UIKit looks for a positional movement of the finger touch which translates into touchedMoved events as the x/y of the finger is changed until the finger is lifted and the touchesEnded event is fired.

If the finger is held down in one place it will not fire the touchesMoved event until there is movement.

I am building an app where you have to draw based on touchesMoved and it does happen at intervals but it is fast enough to give a smooth drawing appearance. Since it is an event and buried in the SDK you might have to do some testing in your scenario to see how fast it responds, depending on other actions or events it could be variable to the situation it is used. In my experience it is within a few ms of movement and this is with about 2-3k other sprites on the screen.

The drawing does start on the touchesBegan event though so the first placement is set then it chains to the touhesMoved and ends with the touchesEnd. I use all the events for the drag operation, so maybe the initial move is less laggy perceptually in this case.

To test in your app you could put a timestamp on each event if it is crucial to your design and work out some sort of easing.

http://developer.apple.com/IPhone/library/documentation/UIKit/Reference/UIResponder_Class/Reference/Reference.html#//apple_ref/occ/instm/UIResponder/touchesMoved:withEvent:

Ryan Christensen
I've done this. For fine movements the first "moved" can be much slower than subsequent moved pairs. Try drawing some connected line segments. The first segment should be longer. The difference is subtle and I think my app is magnifying the effect (it simulates a turntable). Unless there is a lower level interface, I'll just have to minimise the effect.
Rhythmic Fistman
Yes I am using some interpolation and extrapolation for network effect (easing between points and some prediction). But locally you might need this as well. It depends on your app but keep in mind it is still a slow processor and an old computer really so if you have lots of graphics and events there will be delays.
Ryan Christensen
For me this behaviour is a bug, so I'll log it. My app naturally smoothes discontinuities, but it will of course benefit from higher quality multitouch input from UIKit.
Rhythmic Fistman
+1  A: 

I don't represent any kind of official answer but it makes sense that touchesBegan->touchesMoved has a longer duration than touchesMoved->touchesMoved. It would be frustrating to developers if every touchesBegan came along with a bunch of accidental touchesMoved events. Apple must have determined (experimentally) some distance at which a touch becomes a drag. Once the touchesMoved has begun, there is no need to perform this test any more because every point until the next touchesUp is guaranteed to be a touchesMoved.

This seems to be what you are saying in your original post, Rythmic Fistman, and I just wanted to elaborate a bit more and say that I agree with your reasoning. This means if you're calculating a "drag velocity" of some sort, you are required to use distance traveled as a factor, rather than depending on the frequency of the update timer (which is better practice anyway).

Kai
There's nothing intelligent about waiting 0.25 sec until an app gets reported about a dragging intend, if the only logical and possible thing IS an dragging intend (see UISlider for example). Apple must provide us with an option to disable any delay.
Thanks
Exactly @Thanks, also @Kai, perhaps the delay behaviour is desirable for gross input, but you need to be able to turn it off. Also it isn't applied to the other four touches. How do you justify that?
Rhythmic Fistman