TableView onRowTouch response time too long?

Hi,

I’ve set up a simple TableView with 3 elements using the example code found here: http://docs.coronalabs.com/api/library/widget/newTableView.html

Both in the simulator and deployed to a device the response time seems quite off. It seems that the onRowTouch function has a long response time for the pressed event. When tapping the action isn’t recorded and no tap event is printed (when printing at the start of the onRowTouch function). I need to touch the item for about half a second before the action is recorded.

Also when trying to scroll in the list, sometimes it records the press action before the scoll is registered so it changes the item selected in the list when scrolling.

What is the best practice use? Am I doing something wrong? Is it better to use the TableListener to register these events?

Personally I went with TableListener to get my exact desired behaviour. onRowTouch does not feel natural.

Using tableListener you can record x and y location when you touched and when you let go. If its the same x and y it counts as selected. Doesn’t matter if you tap quickly, hold it or whatever. That is the default iOS and Android behaviour AFAIK. 

Thanks for your reply. We ended up using the table listener to get the desired behaviour as well. 

Could you explain with a little code sample what you mean with TableListener for TableView events? Thanks!

This is the way I do it now to get instant feedback, the onRowTouch function is not used, you can copy paste into main to see it work:

[lua]

display.setStatusBar( display.HiddenStatusBar )

local widget = require( “widget” )

local tableView

– Regular method, not used

local function onRowTouch(event) 

    if event.phase == ‘tap’ then

        native.showAlert("Row " … event.target.index, “Selected”)

    end

end

– Table view listener

local startXpos = 0 – Position of finger when you first touch a row

local startYpos = 0

local buffer = 5 – How much you can move your finger around but still be counted as selected

local function tableViewListener(event)

    

    local phase = event.phase

    local row   = event.target

    

    if phase == “began” and not row.selected then

        

        startXpos = event.x

        startYpos = event.y

        row.selected = true

        

    elseif phase == “ended” or phase == “moved” then

        

        row.selected = false

        

        if phase == “ended” and event.y < startYpos + buffer and event.y > startYpos - buffer and event.x < startXpos + buffer and event.x > startXpos - buffer then

            native.showAlert("Row " … row.index, “Selected”)

        end

        

    end

    

end

local function onRowRender( event )

    local row = event.row

    local rowTitle = display.newText( row, "SELECT ME " … row.index, 0, 0, nil, 14 )

    rowTitle.x = display.contentWidth / 2

    rowTitle.y = row.contentHeight * 0.5

    rowTitle:setTextColor( 0, 0, 0 )

end

– Create a tableView

tableView = widget.newTableView {

    width       = display.contentWidth, 

    height      = display.contentHeight,

    onRowRender = onRowRender,

    – onRowTouch  = onRowTouch, – Old

    listener    = tableViewListener, – New

}

tableView:insertRow{rowHeight = 40}

tableView:insertRow{rowHeight = 40}

tableView:insertRow{rowHeight = 40}

[/lua]

I’m just testing while doing that code above.

I really don’t think there is much difference of using onRowTouch handler, just check for both “release” and “tap”.

Seems my code above is redundant right? I’m using build 1188.

EDIT: Never mind, the Tap phase seems not totally reliable perhaps.

[lua]

display.setStatusBar( display.HiddenStatusBar )

local widget = require( “widget” )

local tableView

local function onRowTouch(event) 

    print(event.phase)

    if event.phase == ‘tap’ or event.phase == ‘release’ then

        native.showAlert("Row " … event.target.index, “Selected”)

    end

end

local function onRowRender( event )

    local row = event.row

    local rowTitle = display.newText( row, "SELECT ME " … row.index, 0, 0, nil, 14 )

    rowTitle.x = display.contentWidth / 2

    rowTitle.y = row.contentHeight * 0.5

    rowTitle:setTextColor( 0, 0, 0 )

end

– Create a tableView

tableView = widget.newTableView {

    width       = display.contentWidth, 

    height      = display.contentHeight,

    onRowRender = onRowRender,

    onRowTouch  = onRowTouch,

}

tableView:insertRow{rowHeight = 40}

tableView:insertRow{rowHeight = 40}

tableView:insertRow{rowHeight = 40}

[/lua]

I tested both, on device and simulator, and until now I can’t discover a difference in speed. I have to do further tests within my project. I will report then (will take some time).

Thanks again!

Yeah I’m really not sure if there is noticeable difference anymore, used to be a delay, looks like its gone. Please report back with your findings.

Personally I went with TableListener to get my exact desired behaviour. onRowTouch does not feel natural.

Using tableListener you can record x and y location when you touched and when you let go. If its the same x and y it counts as selected. Doesn’t matter if you tap quickly, hold it or whatever. That is the default iOS and Android behaviour AFAIK. 

Thanks for your reply. We ended up using the table listener to get the desired behaviour as well. 

Could you explain with a little code sample what you mean with TableListener for TableView events? Thanks!

This is the way I do it now to get instant feedback, the onRowTouch function is not used, you can copy paste into main to see it work:

[lua]

display.setStatusBar( display.HiddenStatusBar )

local widget = require( “widget” )

local tableView

– Regular method, not used

local function onRowTouch(event) 

    if event.phase == ‘tap’ then

        native.showAlert("Row " … event.target.index, “Selected”)

    end

end

– Table view listener

local startXpos = 0 – Position of finger when you first touch a row

local startYpos = 0

local buffer = 5 – How much you can move your finger around but still be counted as selected

local function tableViewListener(event)

    

    local phase = event.phase

    local row   = event.target

    

    if phase == “began” and not row.selected then

        

        startXpos = event.x

        startYpos = event.y

        row.selected = true

        

    elseif phase == “ended” or phase == “moved” then

        

        row.selected = false

        

        if phase == “ended” and event.y < startYpos + buffer and event.y > startYpos - buffer and event.x < startXpos + buffer and event.x > startXpos - buffer then

            native.showAlert("Row " … row.index, “Selected”)

        end

        

    end

    

end

local function onRowRender( event )

    local row = event.row

    local rowTitle = display.newText( row, "SELECT ME " … row.index, 0, 0, nil, 14 )

    rowTitle.x = display.contentWidth / 2

    rowTitle.y = row.contentHeight * 0.5

    rowTitle:setTextColor( 0, 0, 0 )

end

– Create a tableView

tableView = widget.newTableView {

    width       = display.contentWidth, 

    height      = display.contentHeight,

    onRowRender = onRowRender,

    – onRowTouch  = onRowTouch, – Old

    listener    = tableViewListener, – New

}

tableView:insertRow{rowHeight = 40}

tableView:insertRow{rowHeight = 40}

tableView:insertRow{rowHeight = 40}

[/lua]

I’m just testing while doing that code above.

I really don’t think there is much difference of using onRowTouch handler, just check for both “release” and “tap”.

Seems my code above is redundant right? I’m using build 1188.

EDIT: Never mind, the Tap phase seems not totally reliable perhaps.

[lua]

display.setStatusBar( display.HiddenStatusBar )

local widget = require( “widget” )

local tableView

local function onRowTouch(event) 

    print(event.phase)

    if event.phase == ‘tap’ or event.phase == ‘release’ then

        native.showAlert("Row " … event.target.index, “Selected”)

    end

end

local function onRowRender( event )

    local row = event.row

    local rowTitle = display.newText( row, "SELECT ME " … row.index, 0, 0, nil, 14 )

    rowTitle.x = display.contentWidth / 2

    rowTitle.y = row.contentHeight * 0.5

    rowTitle:setTextColor( 0, 0, 0 )

end

– Create a tableView

tableView = widget.newTableView {

    width       = display.contentWidth, 

    height      = display.contentHeight,

    onRowRender = onRowRender,

    onRowTouch  = onRowTouch,

}

tableView:insertRow{rowHeight = 40}

tableView:insertRow{rowHeight = 40}

tableView:insertRow{rowHeight = 40}

[/lua]

I tested both, on device and simulator, and until now I can’t discover a difference in speed. I have to do further tests within my project. I will report then (will take some time).

Thanks again!

Yeah I’m really not sure if there is noticeable difference anymore, used to be a delay, looks like its gone. Please report back with your findings.

I’m on 2013.1202 and the delay issue is still there for me. If you use the default listener ‘onRowTouch’, you can’t make fast clicks (simulator) or a fast ‘tap’ in the device. You must tap and hold for a second to trigger whatever you want.

I edited one line of code of the widget_tableview.lua and I think all is working as it should right now.

499. -- If a finger was held down 500. if timeHeld \>= 110 then

Change that delay to 5 and it should work.  :slight_smile:

Cheers,

Cristian.

I’m on 2013.1202 and the delay issue is still there for me. If you use the default listener ‘onRowTouch’, you can’t make fast clicks (simulator) or a fast ‘tap’ in the device. You must tap and hold for a second to trigger whatever you want.

I edited one line of code of the widget_tableview.lua and I think all is working as it should right now.

499. -- If a finger was held down 500. if timeHeld \>= 110 then

Change that delay to 5 and it should work.  :slight_smile:

Cheers,

Cristian.

Thanks so much for the code sample. 

I’m on 1235 and had same tableviews response problems both in Android and iOS. With your code works perfectly.

You are very welcome!  :stuck_out_tongue:

I don’t understand why Corona Team hasn’t fixed this yet. It’s obviously a big issue…Basically the tableView widget is not usable without changing that delay…

Hope they will finally fix it as soon as possible, meanwhile I’ll keep using that ‘patch…’

Cheers.

Thanks so much for the code sample. 

I’m on 1235 and had same tableviews response problems both in Android and iOS. With your code works perfectly.