TableView Row Titles Changing When scrolled

I’m building a poetry app and I’ve used a Tableview to index all of the available poems, but when you scroll it all of the row titles change and become the same. I’ve attached before and after photos to give a better idea of what I’m saying. 

Here is the code that I am calling:

local poems = require("poems") local function onRowRender( event ) local row = event.row local rowHeight = row.contentHeight local rowWidth = row.contentWidth local rowTitle = display.newText( { parent = row, text = poems[poemNum].title, 0,0,nil,fontSize = sizeSetting} ) rowTitle:setFillColor( 0.25,0.25,0.25 ) rowTitle.x = W/2 rowTitle.y = rowHeight/2 end local function onRowTouch( event ) if (event.phase=="tap") then poemNum = event.target.index poemList.isVisible = false poemMain = display.newText( { font = native.systemFont, width = W, fontSize = sizeSetting, x = W/2, y = H/2, text = poems[poemNum].text, align = "center"} ) poemMain.anchorY = -1 poemMain.y = 30 poemMain:setTextColor( 0.3, 0.3, 0.3 ) poemScroll:insert( poemMain ) poemScroll:scrollToPosition( {y=0, time=0} ) poemScroll.isVisible = true poemMain.isVisible = true homeButton.isVisible = false MSbackButton.isVisible = true MSdonateButton.isVisible = true end end function poemButton:tap () bg\_sprite:setSequence( "main" ) bg\_sprite:play( ) ads.show( "banner", {x =0, y=H-90} ) OS\_group.isVisible = false poemList.isVisible = true homeButton.isVisible = true for i=1,#poems do poemNum = i poemList:insertRow{rowHeight=88, rowColor = {}} end end poemList = widget.newTableView ({ top = 98, left = 0, width = W-10, height = H - 196, onRowRender = onRowRender, onRowTouch = onRowTouch, listener = scrollListener }) poemList.isVisible = false

Hi @corymichael.j,

I think there may be some confusion in the value of “poemNum” within “onRowRender()”. Can you print() out the value of “poems[poemNum]” within that function and see what happens when you scroll the view around?

[lua]

print( poems[poemNum] )

print( poems[poemNum].title )

[/lua]

Brent

Ok, I think that helps me understand what’s happening, but not really how to fix it. 

It looks like (as the title suggests) onRowRender is only called when the row comes onscreen? The way the code is currently written is treating it like the rows are all being created at once, but instead they are being created as each row comes on screen, which explains why they title becomes the same for each row as it you scroll around, because they are all moving on and off screen, and as they move onscreen they are referencing the same variable. 

The print function just revealed that the same number and title were being called repeatedly when you scroll. 

You can see in the for loop that the value of poemNum changes incrementally as each row is inserted, and so as the render function calls it once everything is inserted it is only getting one value, so soon enough all of the row titles that reference that variable become the same. 

Now I’m just having trouble thinking of a way to pass an identifier from the for loop to the render that will put the correct title on each row, no matter when it is called. The titles and poems are all currently in a table, and I was using poemNum to reference the corresponding title and poem for each row. 

Usually you would use row.index to get the current row number and pass that.

Hi @corymichael.j,

Did you see the example of how to add custom params to the row when using :insertRow()?

http://docs.coronalabs.com/api/type/TableViewWidget/insertRow.html

Perfect! No I didn’t see that in the API but it was exactly what I was looking for. Thanks. 

Hi @corymichael.j,

I think there may be some confusion in the value of “poemNum” within “onRowRender()”. Can you print() out the value of “poems[poemNum]” within that function and see what happens when you scroll the view around?

[lua]

print( poems[poemNum] )

print( poems[poemNum].title )

[/lua]

Brent

Ok, I think that helps me understand what’s happening, but not really how to fix it. 

It looks like (as the title suggests) onRowRender is only called when the row comes onscreen? The way the code is currently written is treating it like the rows are all being created at once, but instead they are being created as each row comes on screen, which explains why they title becomes the same for each row as it you scroll around, because they are all moving on and off screen, and as they move onscreen they are referencing the same variable. 

The print function just revealed that the same number and title were being called repeatedly when you scroll. 

You can see in the for loop that the value of poemNum changes incrementally as each row is inserted, and so as the render function calls it once everything is inserted it is only getting one value, so soon enough all of the row titles that reference that variable become the same. 

Now I’m just having trouble thinking of a way to pass an identifier from the for loop to the render that will put the correct title on each row, no matter when it is called. The titles and poems are all currently in a table, and I was using poemNum to reference the corresponding title and poem for each row. 

Usually you would use row.index to get the current row number and pass that.

Hi @corymichael.j,

Did you see the example of how to add custom params to the row when using :insertRow()?

http://docs.coronalabs.com/api/type/TableViewWidget/insertRow.html

Perfect! No I didn’t see that in the API but it was exactly what I was looking for. Thanks.