tableView - how to force re-rendering?

How can one force the re-rendering of rows in a  tableView?

Background:  Have rendered level status objects in each row.  All good, however if the score for a level is updated I need a way to re-render (update) the score in that display object which is housed in a row of the tableview.   

Its a few steps.

First you need to start using the new row params when inserting into table, introduced few daily builds back.

[lua]

scene.tableView:insertRow {

        etc = ect

        params  = {score = 123, gameID = 234},

     }

[/lua]

When you are rendering your row you need to use the params.

[lua]

function onRowRender( event )

    

    local row = event.row

    local score = row.params.score

    local gameID = row.params.gameID

    local score = display.newText(row, score, 10, 10, native.systemFont, 10)

    – Make a reference to the score object in the row group so we can access it later

    row.scoreObject = score

    

end

[/lua]

When the score changes you need to iterate through your tableView and change the params:

[lua]

function updateScore(newScore, gameID)

    local tableViewRows = tableView._view._rows

    

    for k, row in ipairs(tableViewRows) do

        local rowGameID = row.params.gameID

        local rowScore = row.params.score

        

        if rowGameID == gameID then

            rowScore = newScore

            – Now when row is rerendered, that is if you scroll a row off screen and on screen again the score will be updated because the params it uses to render the score is updated. However already rendered (visible rows) will not change. So you need to add that .

            if row._view then   – Update row if its currently rendered

                row._view.scoreObject.text = newScore

            end

        end

    end

end

[/lua]

oh great thanks - had not come across this - will try this now

re “tableView._view._rows” - is it ok to reference the rows in this manner? i.e. not subject to break in a future release? (sorry - still new lua and not sure about the underscore exactly and how this is used)

Yeah I understand your concern :slight_smile:  This is hackish and not future proof but only way I know. If you are not in hurry you can try waiting for row re-render function that Corona has said they will be bringing back (it was in previous widgets). I don’t know when that will be though.

ok thanks - this method is better than the other work arounds I’m been trying in the last couple of hours  :)

@coronalabs - +1 from myself re implementing re-render

Have had one problem with the use of row params.   I have added my custom “object” in each row which houses ( a group object ) other display objects that make up the level indicator (e.g. text, a few images).   

What seems to happen is when you scroll down the tableView a bit (so several rows get rendered) then go out and back into this scene the initial rows seem to “drop” the display objects.   So lets say my display group that I was adding to tableView row via params was:

  • MyGroup

   - level number = 5

   - text = “asdfasdf”

   - my images = { image1, image2 etc }

The number & text is remembers, however the images table is an empty table.   So as if Corona when to flush that row but kept some parts of it. 

I guess in my work around when iterating through all rows I will need to check the contents of the arrays, if if not there then recreate the “MyGroup” object for it I guess.

Would be really good to have a proper “re-render row”

Update:

Have managed to get a work around so things are working.  My notes:

* Main issue is that when Corona seems to mark a row (no longer displayed) for “re-use” it does not seem to remove/clean up the row contents, and in particular some aspects of the row.params seem to say intact and others do not

* It would be good if Corona could either (a) completely clear the row in this case or at least (b) provide an event so we could clean up ourselves

WorkAround

* In “enterScene” when looping through rows in  tableView._view._rows I implemented a specific check of my display group within the row to see if it was fully intact.  If it was not I just do not attempt to update it.  (e.g. using next(myDisplayObject) == nil check)

* Also in the “renderRow” event I make sure I delete any row.params objects still hanging around before starting afresh.

Its a few steps.

First you need to start using the new row params when inserting into table, introduced few daily builds back.

[lua]

scene.tableView:insertRow {

        etc = ect

        params  = {score = 123, gameID = 234},

     }

[/lua]

When you are rendering your row you need to use the params.

[lua]

function onRowRender( event )

    

    local row = event.row

    local score = row.params.score

    local gameID = row.params.gameID

    local score = display.newText(row, score, 10, 10, native.systemFont, 10)

    – Make a reference to the score object in the row group so we can access it later

    row.scoreObject = score

    

end

[/lua]

When the score changes you need to iterate through your tableView and change the params:

[lua]

function updateScore(newScore, gameID)

    local tableViewRows = tableView._view._rows

    

    for k, row in ipairs(tableViewRows) do

        local rowGameID = row.params.gameID

        local rowScore = row.params.score

        

        if rowGameID == gameID then

            rowScore = newScore

            – Now when row is rerendered, that is if you scroll a row off screen and on screen again the score will be updated because the params it uses to render the score is updated. However already rendered (visible rows) will not change. So you need to add that .

            if row._view then   – Update row if its currently rendered

                row._view.scoreObject.text = newScore

            end

        end

    end

end

[/lua]

oh great thanks - had not come across this - will try this now

re “tableView._view._rows” - is it ok to reference the rows in this manner? i.e. not subject to break in a future release? (sorry - still new lua and not sure about the underscore exactly and how this is used)

Yeah I understand your concern :slight_smile:  This is hackish and not future proof but only way I know. If you are not in hurry you can try waiting for row re-render function that Corona has said they will be bringing back (it was in previous widgets). I don’t know when that will be though.

ok thanks - this method is better than the other work arounds I’m been trying in the last couple of hours  :)

@coronalabs - +1 from myself re implementing re-render

Have had one problem with the use of row params.   I have added my custom “object” in each row which houses ( a group object ) other display objects that make up the level indicator (e.g. text, a few images).   

What seems to happen is when you scroll down the tableView a bit (so several rows get rendered) then go out and back into this scene the initial rows seem to “drop” the display objects.   So lets say my display group that I was adding to tableView row via params was:

  • MyGroup

   - level number = 5

   - text = “asdfasdf”

   - my images = { image1, image2 etc }

The number & text is remembers, however the images table is an empty table.   So as if Corona when to flush that row but kept some parts of it. 

I guess in my work around when iterating through all rows I will need to check the contents of the arrays, if if not there then recreate the “MyGroup” object for it I guess.

Would be really good to have a proper “re-render row”

Update:

Have managed to get a work around so things are working.  My notes:

* Main issue is that when Corona seems to mark a row (no longer displayed) for “re-use” it does not seem to remove/clean up the row contents, and in particular some aspects of the row.params seem to say intact and others do not

* It would be good if Corona could either (a) completely clear the row in this case or at least (b) provide an event so we could clean up ourselves

WorkAround

* In “enterScene” when looping through rows in  tableView._view._rows I implemented a specific check of my display group within the row to see if it was fully intact.  If it was not I just do not attempt to update it.  (e.g. using next(myDisplayObject) == nil check)

* Also in the “renderRow” event I make sure I delete any row.params objects still hanging around before starting afresh.

Hi guys,

I don’t fully understand what you’re doing here, but it might come in handy for my project… I’m trying to use the textNumber.text value (which is generated and modified in-row) from the onRowRender function and use it outside of it.

How should I proceed (if you think it’s doable in this case)??

here’s the snippet:

function onRowRender( event )     local row = event.row     local rowHeight = row.contentHeight     local rowWidth = row.contentWidth     local textNumber = display.newText( row, 0, 0, 0, "Helvetica", 25)     textNumber.x = rowWidth - 40     textNumber.y = rowHeight / end

Hi guys,

I don’t fully understand what you’re doing here, but it might come in handy for my project… I’m trying to use the textNumber.text value (which is generated and modified in-row) from the onRowRender function and use it outside of it.

How should I proceed (if you think it’s doable in this case)??

here’s the snippet:

function onRowRender( event )     local row = event.row     local rowHeight = row.contentHeight     local rowWidth = row.contentWidth     local textNumber = display.newText( row, 0, 0, 0, "Helvetica", 25)     textNumber.x = rowWidth - 40     textNumber.y = rowHeight / end