Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Understanding sample code for "onRowTouch" event
Started by ammar71 Dec 17 2019 08:35 AM

8 replies to this topic
onrowtouch tableview

Best Answer XeduR @Spyric , 17 December 2019 - 08:48 AM

1) "event.x and event.xStart" part checks if the touch event began, i.e. has a start value, and if it also has a current value for x, this is done to prevent the app from crashing if the user were to touch the screen and slide their finger on the button, at which point no "began" phase would occur. The math.abs( ... ) part then determines if the user has dragged their finger more than 10 pixels to either side from the starting location, at which point it will interpret the user's touch as not being intended to activate that button. This is typically done to prevent accidental touches/taps, because most touch/tap events should be about just touching a button and lifting one's finger.

2) cancelled occurs when the OS ends the touch event instead of the user. This is quite rare, but worth taking into account.

3) You put in "return true" to prevent touch propagation. That is, if you don't want a touch event to trigger any other functions below the current display object, then you'd return true. If you don't have "return true", then a touch will trigger any and all possible touch events for objects that are placed on top of each other.

[TOPIC CONTROLS]
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

ammar71

[GLOBAL: userInfoPane.html]
ammar71
  • Enthusiast

  • 98 posts
  • Corona SDK

Hi all,

 

I have recently discovered the sample code that comes with Corona and I am trying to learn from it. One piece of code that I didn't understand was from a smaple project under Graphics\FilterViewer. The code is as follows:

local function onRowTouch( event )
    if ( event.target.canTest == false ) then return end

    if ( event.phase == "press" ) then
        list.actionOnRelease = true
    elseif ( event.phase == "cancelled" ) then
        list.actionOnRelease = false
    end

    if ( "release" == event.phase and list.actionOnRelease == true ) then

        list.actionOnRelease = false
        ...
        .... Some other code goes here ...
        ...
    end
end

local function scrollListener( event )
    if ( event.x and event.xStart and ( math.abs( event.x - event.xStart ) > 10 ) ) then
        list.actionOnRelease = false
    end
    return true
end 

Can someone please explain to me:

1- What are we trying to achieve by setting the list.actionOnRelease to false/true.

2- What is a "cancelled" phase?

3- The "onRowTouch" function doesn't return "true" while the "scrollListener" does. Why/When do we need to return true?

 

I looked at

https://docs.coronalabs.com/api/type/TableViewWidget/index.html

but it doesn't mention the "cancelled" phase.

 

Thanks.



[TOPIC: post.html]
#2

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Corona Geek

  • 1,249 posts
  • Corona SDK

  Best Answer

1) "event.x and event.xStart" part checks if the touch event began, i.e. has a start value, and if it also has a current value for x, this is done to prevent the app from crashing if the user were to touch the screen and slide their finger on the button, at which point no "began" phase would occur. The math.abs( ... ) part then determines if the user has dragged their finger more than 10 pixels to either side from the starting location, at which point it will interpret the user's touch as not being intended to activate that button. This is typically done to prevent accidental touches/taps, because most touch/tap events should be about just touching a button and lifting one's finger.

2) cancelled occurs when the OS ends the touch event instead of the user. This is quite rare, but worth taking into account.

3) You put in "return true" to prevent touch propagation. That is, if you don't want a touch event to trigger any other functions below the current display object, then you'd return true. If you don't have "return true", then a touch will trigger any and all possible touch events for objects that are placed on top of each other.


  • pixec likes this

[TOPIC: post.html]
#3

pixec

[GLOBAL: userInfoPane.html]
pixec
  • Contributor

  • 210 posts
  • Corona SDK

If you have many touch listeners, how do you know what function needs return true?

[TOPIC: post.html]
#4

ammar71

[GLOBAL: userInfoPane.html]
ammar71
  • Enthusiast

  • 98 posts
  • Corona SDK

Thanks @XeduR

 

For number 1, we are only checking the x values. What about sliding vertically (the y values)?

Wouldn't looking for a "tap" event instead of a "press" event solve this problem?

 

For number 3, does a touch event get sent to scrollListener, onRowTouch or both?

Why did the code (in this case) return true for scrollListener but not onRowTouch (i.e. why did we want the event to propagate further in one but not the other)?



[TOPIC: post.html]
#5

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Corona Geek

  • 1,249 posts
  • Corona SDK

Since it's a scroll listener, it may be that y movement is considered a more natural part of the movement (since the entire plan is to scroll the entries vertically to begin with), so only excessive x movement is undesired. You could use a tap listener, but the two events are different. Also,  Touch events are more forgiving as a tap event will not fire if you were to touch, move your finger a few pixels on the screen and then lift your finger.

 

A touch event gets sent to all touch event listeners that are present on the location in the order that they are available. So, if you were to place 10 display objects on top of each other and they all had a touch event listener, then all listeners will fire unless there is a return true at the end of one of the listeners after which no further listeners will fire.

 

The simple answer to why allow for touch events to propagate is that you have some additional functionality outside of a single function that you want to keep track of.


  • ammar71 likes this

[TOPIC: post.html]
#6

ammar71

[GLOBAL: userInfoPane.html]
ammar71
  • Enthusiast

  • 98 posts
  • Corona SDK

Thanks @XeduR



[TOPIC: post.html]
#7

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 26,682 posts
  • Enterprise

I've not looked at the tableView code in a long time, but if I remember correctly, the widget is using touch to determine things, but it's generating it's own events and passing data to the two primary listener functions. Neither will a pure touch event. For example there is no "press" event generated by "touch". 

 

onRowTouch() gets called when we detect a touch on a row after filtering out movement. I don't believe we try and catch "tap" events, of we do, it's to block them from propagating on.

 

The scrollListener event is for things like reaching the end of the tableView, if the tableView was pulled down past the first row, etc. while onRowTouch is just for interacting with the row.

 

Rob



[TOPIC: post.html]
#8

ammar71

[GLOBAL: userInfoPane.html]
ammar71
  • Enthusiast

  • 98 posts
  • Corona SDK

@Rob

 

I've added a print(event.phase) to onRowTouch and I can see "tap", "press" and "release" phases printed.

 

It seems to me that the sample code for the "FilterViewer" project is over complicating things and using:

if event.phase == "tap"

would achieve the same result.



[TOPIC: post.html]
#9

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 26,682 posts
  • Enterprise

Thanks for reminding me. Yes, there is a tap event. I believe it's there so you can do long presses to do things like slide out delete buttons, slide the row left and right, scroll, etc. Tap is defined a a short duration up and down with no movement. So the tap event is likely there so you can use press and release to do things and use tap to say the row was clicked on.

 

Rob




[topic_controls]
[/topic_controls]

Also tagged with one or more of these keywords: onrowtouch, tableview