How to stop propagating tap events?

Hello all,

I have layers of display objects on top of each other. Each display object has both (1) touch listener, and (2) tap listener, to action upon either or / both touch event and tap event.

I have used “return true” in touch listener in successfully stopping the propagating of touch events from top object to the one below. I also use “return true” in tap listener, but it does not stop the propagating of tap event (from top object to the one below).

How do one stop tap event from propagating downwards?

Thank you.

Regards, Luan

PS> In my program, I need to use both touch and tap events, and to have different actions, based upon, if touch event (and phase), and if tap event (and number of taps).

This is tested with Simulator 2018.3258 (Apr  4 2018) on Windows 10, as well as on a Samsung Tablet running Android 4.4.2.

It would be easier to help if you posted some simple code showing the problem.

The changes are that you don’t need to use both listeners.

Also, it is extremely unlikely that return true is not preventing the tap event from propagating. This is something which a lot of developers get wrong and think is a bug, until they have enough experience with to understand it properly.

You can just use a touch listener and count taps in a time period on your own.  I agree with @horacebury, you don’t need to use a tap  + touch listener.

A touch listener distinguishing between tap and touch could look like this:

local touchstart function touchListener(event) -- if new touch if(event.phase=="began") then -- set starting time touchstart = event.time -- do something -- while dragging elseif(event.phase=="moved") then -- do something -- on removing finger elseif(event.phase=="ended") then -- calculate time user touched display touchtime1 = event.time - touchstart -- in case time is under 150ms, consider it a tap if(touchtime1 \< 150) then -- do something -- in case time is over 150ms, consider it touch else -- do something else end end end

Correct me if I’m wrong, but the only significant difference between a touch event and a tap event is that a tap event can only go from “began” to “ended” phase, whereas a touch event can have the “moved” phase. Therefore, if the user doesn’t move their finger around on the screen, then there is no “moved” phase, i.e. they just tapped the screen.

Detecting taps using touch events is as simple as:

 

local object = display.newRect(240,160,100,100) local tapOrTouch, tapTime, tapCount local timeBetweenTaps = 250 local function onObjectTouch( event ) if ( event.phase == "began" ) then tapOrTouch = "tap" elseif ( event.phase == "moved" ) then tapOrTouch = "touch" elseif ( event.phase == "ended" ) then print( "The event was: "..tapOrTouch ) if tapOrTouch == "tap" then if tapTime == nil then tapCount = 1 tapTime = event.time else if event.time-tapTime \<= timeBetweenTaps then tapCount = tapCount+1 else tapCount = 1 end tapTime = event.time print("number of taps is: "..tapCount) end end end return true end object:addEventListener( "touch", onObjectTouch )

Hello all,

Many thanks for your prompt response, and the great idea of using “touch” to differentiate “tap”. If I had done this, it would allow me to have better focus on the events and the response of these events in my code. Thanks for sharing the code to illustrate the idea. I would certainly want to use it.

Once again, many thanks for your sharing. It is a good day, as I have learned something new again.

On the problem of “tap propagating”, I have unnecessarily complicated my codes to have these events in two or more places, and on, with many variables, in different modules, such as looking for number of taps, before or after, the time held on the touch and so on. This makes it harder for me to troubleshoot the problem I faced.

It is not a bug. It is my code.

The good news is that, return = true, in tap listener, does in fact stop the propagating. So there is no bug in Simulator, nor any error in the Corona documentation.

The cause of my problem was in my own code. In one situation, when a certain sequence and number of taps, I wanted to make the display object “disappear”. I did that with translate and isVisible. But it looks like “return = true” was not executed, before the object “disappear”. At the end, I add a delay of 200ms, to ensure that “return = true” get executed before the object “disappear”. Of course, it is not obvious to a user, but makes the difference to my code.

Once again. Thank you for your time and sharing! They are most appreciated.

Regards, Luan

It would be easier to help if you posted some simple code showing the problem.

The changes are that you don’t need to use both listeners.

Also, it is extremely unlikely that return true is not preventing the tap event from propagating. This is something which a lot of developers get wrong and think is a bug, until they have enough experience with to understand it properly.

You can just use a touch listener and count taps in a time period on your own.  I agree with @horacebury, you don’t need to use a tap  + touch listener.

A touch listener distinguishing between tap and touch could look like this:

local touchstart function touchListener(event) -- if new touch if(event.phase=="began") then -- set starting time touchstart = event.time -- do something -- while dragging elseif(event.phase=="moved") then -- do something -- on removing finger elseif(event.phase=="ended") then -- calculate time user touched display touchtime1 = event.time - touchstart -- in case time is under 150ms, consider it a tap if(touchtime1 \< 150) then -- do something -- in case time is over 150ms, consider it touch else -- do something else end end end

Correct me if I’m wrong, but the only significant difference between a touch event and a tap event is that a tap event can only go from “began” to “ended” phase, whereas a touch event can have the “moved” phase. Therefore, if the user doesn’t move their finger around on the screen, then there is no “moved” phase, i.e. they just tapped the screen.

Detecting taps using touch events is as simple as:

 

local object = display.newRect(240,160,100,100) local tapOrTouch, tapTime, tapCount local timeBetweenTaps = 250 local function onObjectTouch( event ) if ( event.phase == "began" ) then tapOrTouch = "tap" elseif ( event.phase == "moved" ) then tapOrTouch = "touch" elseif ( event.phase == "ended" ) then print( "The event was: "..tapOrTouch ) if tapOrTouch == "tap" then if tapTime == nil then tapCount = 1 tapTime = event.time else if event.time-tapTime \<= timeBetweenTaps then tapCount = tapCount+1 else tapCount = 1 end tapTime = event.time print("number of taps is: "..tapCount) end end end return true end object:addEventListener( "touch", onObjectTouch )

Hello all,

Many thanks for your prompt response, and the great idea of using “touch” to differentiate “tap”. If I had done this, it would allow me to have better focus on the events and the response of these events in my code. Thanks for sharing the code to illustrate the idea. I would certainly want to use it.

Once again, many thanks for your sharing. It is a good day, as I have learned something new again.

On the problem of “tap propagating”, I have unnecessarily complicated my codes to have these events in two or more places, and on, with many variables, in different modules, such as looking for number of taps, before or after, the time held on the touch and so on. This makes it harder for me to troubleshoot the problem I faced.

It is not a bug. It is my code.

The good news is that, return = true, in tap listener, does in fact stop the propagating. So there is no bug in Simulator, nor any error in the Corona documentation.

The cause of my problem was in my own code. In one situation, when a certain sequence and number of taps, I wanted to make the display object “disappear”. I did that with translate and isVisible. But it looks like “return = true” was not executed, before the object “disappear”. At the end, I add a delay of 200ms, to ensure that “return = true” get executed before the object “disappear”. Of course, it is not obvious to a user, but makes the difference to my code.

Once again. Thank you for your time and sharing! They are most appreciated.

Regards, Luan