Please post your code using the <> button in the bar with Bold, Italic, etc.
You have no control over when onRowRender() is called. The tableView code will call it when it needs to render a row. If rows are off screen they are disposed of to keep memory low. When it’s ready to bring a row on the screen, it calls this function and the row is created and then brought on screen.
Because of this you can’t use global or upvalue variables like messageToRender because it’s value changes as your insert loop runs and it basically only remembers the last item.
There are two ways to handle this. One is to use an array of messageToRender values that are indexed to match the row.index value. The first item in your data array needs to match what you expect the first row of your tableView to be. Let’s look at an example:
local messagesToRender = {} local function onRowRender( event ) local row = event.row local rowTitle = display.newText( row, "Row " .. row.index .. messagesToRender[row.index] ) , 0, 0, nil, 12 ) --rowTitle:setReferencePoint( display.CenterLeftReferencePoint ) rowTitle.x = 0 rowTitle.anchorX = 0 rowTitle:setFillColor( 5 ) rowTitle.y = row.contentHeight \* 0.5 end
local function LoadSavedGame ( event ) LoadSavedMessages = DB.getAllSavedMessages() for i = 1, #LoadSavedMessages do messagesToRender[i] = (LoadSavedMessages[i]) print( "LoadSavedMessages "..messagesToRender[i]) tableView:insertRow { isCategory = isCategory, rowHeight = 40, rowColor = {default = { 255, 255, 255, 0 },} } end end
This works assuming there is a one-to-one relationship between the data table and the tableView rows. If you start adding category rows in, or you delete data rows in the middle of the table all bets are off.
In programming there is a concept known as MVC (Model View Controller). I don’t personally like the choice of words in the concept, but basically the Model is your database, it’s scheme and other data structures that make up your data. The View is what actually gets displayed to the user. What makes MVC popular is that it’s designed so that you can change the database and you can change the display at any time without having to effect the other. That’s where the C or controller comes in. It’s the code that maps the data to the view.
In this case, your view is the tableView and each of it’s rows. Your data is your database of information. The controller is the loadSavedGame() function basically. Your data doesn’t need to know how onRowRender works. onRowRender doesn’t care how you get the data from the database. You let the controller do the work.
I proposed this a couple of posts back. The tableView:insert() method supports passing in the data **WITH** the insert call. This lets your data be the data (onRowRender needs to not know anything about the LoadSavedMessages table. You include the data with the insert call. Each row now knows specifically what data goes with it.
You’re code might now look like:
local function onRowRender( event ) local row = event.row local messageToRender = event.row.params.messageToDisplay local rowTitle = display.newText( row, "Row " .. row.index .. messageToRender ) , 0, 0, nil, 12 ) rowTitle.x = 0 rowTitle.anchorX = 0 rowTitle:setFillColor( 5 ) rowTitle.y = row.contentHeight \* 0.5 end local function LoadSavedGame ( event ) local LoadSavedMessages = DB.getAllSavedMessages() for i = 1, #LoadSavedMessages do tableView:insertRow { isCategory = isCategory, rowHeight = 40, rowColor = {default = { 255, 255, 255, 0 },}, params = { messageToDisplay = LoadSavedMessages[i] }, } end end
I personally would go with the latter. MVC will simplify your life in the end.
Rob