newTableView scrolling error

Hi Dave,

I inspected your project and determined that the crash is because you’re calling “:reloadData()” during the touch (all phases with no conditional filtering). That causes the TableView to think that it has been “reset” and then it registers the ability to re-press the row (even though it’s already pressed) in an endless sequence until you release. During this time, if you slide downward off the row, it crashes.

The typical purpose of “:reloadData()” is a one-time call to refresh the TableView after you’ve changed its intended content around… so you’re not exactly “wrong” to be using it for updating the little red dots in each row, but calling it during the touch phase is causing a sort of recursive loop and a liable crash.

Personally, I would handle this in a more simple way. Instead of doing all of the code with checking “rowSlot” and “iNew” and such, I would just loop through the visible rows of the TableView in the “press” phase of the touch… it’s very important that you filter out which phase of the row touch is being handled!

In the loop, check if the row currently being pressed is the same as the one being referenced by the loop index. If so, turn your little red dot on, and possibly update some other variable you need for tracking which row is selected. For the others, turn off the red dot.

This code shows how you might approach it:

local function onFromRowTouch(event) local phase = event.phase local row = event.target local id = row.index if ( phase == "press" ) then for i = 1,deviceTableViewFrom:getNumRows() do local thisRow = deviceTableViewFrom:getRowAtIndex( i ) if ( thisRow ~= nil and thisRow.isCategory == false ) then if ( id == thisRow.index ) then print( "MARK ROW " .. id .. " AS SELECTED (WITH RED DOT)" ) if ( thisRow.selOn and thisRow.selOff ) then thisRow.selOn.isVisible = true thisRow.selOff.isVisible = false end else if ( thisRow.selOn and thisRow.selOff ) then thisRow.selOn.isVisible = false thisRow.selOff.isVisible = true end end end end end end

Hope this helps somewhat,

Brent

oh, you’re good.

Thanks, Brent.  

Since the press event only comes on a long press, I added tap into the if, which made it appear more responsive.  Some day, I’d like to know how you were able to track and identify this.

Below is what I ended up with.  I left the reset of my table in case you guys ever moved the params out of the view when its de-rendered.

Thanks again.

Dave

 if (phase == "tap" or phase == "press") then resetFromTable() -- set all arrayElements to untouched for i=1, deviceTableViewFrom:getNumRows() do local thisRow = deviceTableViewFrom:getRowAtIndex( i ) if (thisRow ~= nil and thisRow.isCategory == false) then if ( id == thisRow.index ) then fromRowSelectedPair = row.params.pairCode or "" fromRowSelectedID = row.params.rowDataID fromTable[thisRow.params.rowSlot] = true thisRow.selOn.isVisible = true thisRow.selOff.isVisible = false else fromTable[thisRow.params.rowSlot] = false thisRow.selOn.isVisible = false thisRow.selOff.isVisible = true end end end end

That looks reasonable. And yes, usually I use both “tap” and “press” for TableView rows, since some users may not press long enough to trigger the “press”. Note that you can change how long it takes to register a press… default is 110 milliseconds… but you should test carefully because if you shorten it, you might get a “press” when you merely want to slide/drag the view. On the flip side, making it longer than 110 might seem too slow for users who expect a longer press (but then again, making it around 120-150 AND having a tap might be a nice combination… again, you should experiment to see what feels right to you).

https://docs.coronalabs.com/api/library/widget/newTableView.html#rowtouchdelay-optional