event.phase == "ended" is being missed during fast swipe and release

I've found that if your finger (or mouse) is moving quickly across the screen (fast swipe) when you lift it, the "ended" event.phase is sometimes missed.

Steps to reproduce:
1. touch and hold your finger/mouse to the screen
2. quickly swipe your finger/mouse across the screen
3. lift your finger/mouse while still swiping
4. notice that "ended" does not always print to the terminal (when using the following example code).

Here's a simple example to test with:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
local function touchMyRectangle(event) 
        local phase = event.phase
                        
        if phase == "began" then
                print("began")
        end
        
        if phase == "ended" or phase == "cancelled" then
                print("ended")
        end
end
 
 
local myRectangle = display.newRect(0, 0, 480, 320)
myRectangle:setFillColor(255, 255, 255, 100)
myRectangle:addEventListener( "touch", touchMyRectangle )

*EDIT/UPDATE*
If you change

1
myRectangle:addEventListener( "touch", touchMyRectangle )

Your rectangle isn't receiving a touch.phase.ended event because the touch is ending outside of the rectangle.

For the rectangle to capture all successive touch events after "began", use display.getCurrentStage():setFocus( myRectangle ) inside of the "began" handler, and then release focus inside of the "ended" event by passing "nil" to the stage:SetFocus( nil ) method.

Hello,

I have tried the same thing. It is not working. I am not getting the 'ended' phase if I use multiple fingers. Should I report it as a bug or am I doing something wrong ? Please help!!

Thanks

You are doing it wrong. Read docs on multitouch.

Thanks for super quick reply!

I haven't enabled multi-touch. Should I enable multi-touch?

I have a button in my game. When I quickly swipe it or simultaneously touch the button & background, I am not getting 'ended' phase.

@singh206, thanks for the replay but that doesn't fix the problem. If you're using my example above, you'll notice that the rectangle is 480x320 (same size as the screen) so it's impossible for the touch to end outside the rectangle unless you're completely off the screen.

The issue I'm reporting is that "ended" events are sometimes missed if you're swiping quickly and lift your finger while still within the bounds of the rectangle.

Here's a revised script with your suggested additions. Steps to reproduce the bug are the same:

1. quickly swipe your finger across the screen.
2. while still within the bounds of the rectangle, lift your finger.
3. watch the terminal output and notice that "ended" does not always print when lifting your finger.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
local function touchMyRectangle(event) 
        local phase = event.phase
                        
        if phase == "began" then
                print("began")
                display.getCurrentStage():setFocus(myRectangle)
        end
        
        if phase == "ended" or phase == "cancelled" then
                print("ended")
                display.getCurrentStage():setFocus(nil)
        end
end
 
 
local myRectangle = display.newRect(0, 0, 480, 320)
myRectangle:addEventListener( "touch", touchMyRectangle )

@tim

Interesting, I haven't noticed this behavior yet in any of my apps using touch events. Which build are you using? And which iPhone?

Build: 2011.484
iPhone 3GS OS 4.3.3

But the problem occurs in the Simulator just as easily as on the device using the code example I provided.

@tim

Is that the entirety of your code? I'm not experiencing the issue. Ended is firing always.

@singh206 yep that's all the code and I get get the ended to miss about 2 in 10 tries. It's not easy to reproduce, but it's easy enough to reproduce that some people playing my game will certainly experience it.

I'll put together another example the demonstrates the issue more clearly than watching for text output at the console.

Ok, ended is always caught with the following. After adding SetFocus(), I forgot to move the newRect() line above the function. At least I think that's what the problem was.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
local myRectangle = display.newRect(0, 0, 480, 320)
 
local function touchMyRectangle(event) 
        local phase = event.phase
                        
        if phase == "began" then
                print("began")
                display.getCurrentStage():setFocus(myRectangle)
        end
        
        if phase == "ended" or phase == "cancelled" then
                print("ended")
                display.getCurrentStage():setFocus(nil)
        end
end
 
myRectangle:addEventListener( "touch", touchMyRectangle )

I had the same issue right now -- fast swipes causing the event to get "stuck" without apparent end -- but fixed it by passing event.id as the touchId parameter both when setting and nilling the focus:

display.getCurrentStage():setFocus(displayObject [,touchID])

http://developer.anscamobile.com/reference/index/stagesetfocus

views:1868 update:2011/10/11 22:13:38
corona forums © 2003-2011