iOS Development in Flash: TouchEvent.TOUCH_TAP with TouchEvent.TOUCH_BEGIN/TOUCH_END

Too bad we can't use the both Multitouch input modes in the IOS Packager for Flash/Air/Flex. It's either gesture or touch, so you have to decide on which suits your application better.
For my current project I decided on MultitouchInputMode.TOUCH due to better interaction with what I was trying to do.
I had objects aligned on the x coordinate that I wanted to move according to the touch input and, when tapped (or clicked) on, they were supposed to do something. The point where I got in trouble was that the TOUCH_TAP event (just like MouseEvent.CLICK) would fire even when I had slided the objects using TOUCH_BEGIN beforehand. So the device makes no difference there which is in a way understandable but sometimes not so useful.
Now during testing it turned out that the TOUCH_TAP event is fired before TOUCH_END which comes in handy. If we make use of the events properties and the TOUCH_MOVE event, we can check if our object has in fact moved and if no, it's okay for the tap event to execute whatever it was made for.
In fact it turned out that sometimes the event would fire before, sometimes after. So in the end I made a little workaround by adding a timer, that would set the offsetX to 0 only after 100 milliseconds have passed. Works now but there should be a better solution. If you have one, let me know!

The code looks like this:


private var touchedX:int = 0;
private var touchedY:int = 0;
private var offsetX:int = 0;
function init(){
 myBtn.addEventListener(TouchEvent.TOUCH_TAP, clicked);
 Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
 myBtn.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchBegin);
 myBtn.addEventListener(TouchEvent.TOUCH_MOVE, onTouchMove);
 myBtn.addEventListener(TouchEvent.TOUCH_END, onTouchEnd);
}

function clicked(e:TouchEvent):void {
 if(offsetX == 0){
  // do stuff
 }
}

function onTouchBegin(eBegin:TouchEvent) {
 killTimer();
 touchedX = eBegin.stageX;
 touchedY = eBegin.stageY;
 offsetX=0;
 myBtn.startTouchDrag(eBegin.touchPointID, false, new Rectangle(0,0,300,0);
}
function onTouchMove(eMove:TouchEvent) {
 offsetX = touchedX - eMove.stageX;
}
function onTouchEnd(eEnd:TouchEvent) {
 myBtn.stopTouchDrag(eEnd.touchPointID);
 startTimer();
}

private var resTim:Timer = new Timer(100,1);
private function killTimer():void {
 resTim.reset();
 resTim.removeEventListener(TimerEvent.TIMER_COMPLETE, resetOffset);
}
private function startTimer():void {
 resTim.addEventListener(TimerEvent.TIMER_COMPLETE, resetOffset);
 resTim.reset();
 resTim.start();
}
private function resetOffset(e:TimerEvent):void {
 offsetX = 0;
 killTimer();
}


Basically I keep track of any touch movements through the TOUCH_MOVE event and reset the offsetX parameter in my event handler for TOUCH_END. If the user just taps on the object, the TOUCH_BEGIN is fired (i believe) but because offsetX is not changed there, it's ok to continue.
This was tested using an iPhone 4.

Kommentare

Beliebte Posts aus diesem Blog

Play M3U8 HTTP Stream through Flash Player using apple-http-osmf

Drawing a line after an arrow that follows a path in a Flash MovieClip

Dropping Clips on Sprite Graphics V2