TableView Category Not Rendering Properly

Hi guys @ Corona,

I actually filed this up as a bug sometime ago, but no response was received. I am posting it here, incase someone else has a solution.

The problem is that when tableView widget is used with a lot of ‘isCategory’ items, the rendering is buggy, where some items will not appear properly. Based on the screen shot below, the row #7, #12, #13 is missing. This happens randomly.

This only occurs when scrolling pretty fast and when there is lots of ‘isCategory’. 

Here is the sample code (taken from ‘WidgetDemo’ sample app).

Note : I am on Corona Mac ‘Version 2013.1251 (2013.11.1)’, but it happens on older versions when used previously.

--\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -- -- ==================================================================== -- Corona SDK "Widget" Sample Code -- ==================================================================== -- -- File: main.lua -- -- Version 2.0 -- -- Copyright (C) 2013 Corona Labs Inc. All Rights Reserved. -- -- Permission is hereby granted, free of charge, to any person obtaining a copy of -- this software and associated documentation files (the "Software"), to deal in the -- Software without restriction, including without limitation the rights to use, copy, -- modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, -- and to permit persons to whom the Software is furnished to do so, subject to the -- following conditions: -- -- The above copyright notice and this permission notice shall be included in all copies -- or substantial portions of the Software. -- -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -- INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -- PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE -- FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -- DEALINGS IN THE SOFTWARE. -- -- Published changes made to this software and associated documentation and module files (the -- "Software") may be used and distributed by Corona Labs, Inc. without notification. Modifications -- made to this software and associated documentation and module files may or may not become -- part of an official software release. All modifications made to the software will be -- licensed under these same terms and conditions. -- --\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* local widget = require( "widget" ) local storyboard = require( "storyboard" ) local scene = storyboard.newScene() -- Our scene function scene:createScene( event ) local group = self.view -- Forward reference for our tableView local tableView = nil -- Text to show which item we selected local itemSelected = display.newText( "You selected item ", 0, 0, native.systemFontBold, 28 ) itemSelected:setTextColor( 0 ) itemSelected.x = display.contentWidth + itemSelected.contentWidth \* 0.5 itemSelected.y = display.contentCenterY - itemSelected.contentHeight group:insert( itemSelected ) -- Function to return to the list local function goBack( event ) --Transition in the list, transition out the item selected text and the back button transition.to( tableView, { x = 0, time = 400, transition = easing.outExpo } ) transition.to( itemSelected, { x = display.contentWidth + itemSelected.contentWidth \* 0.5, time = 400, transition = easing.outExpo } ) transition.to( event.target, { x = display.contentWidth + event.target.contentWidth \* 0.5, time = 400, transition = easing.outQuad } ) end -- Back button local backButton = widget.newButton { width = 198, height = 59, label = "Back", onRelease = goBack, } backButton.x = display.contentWidth + backButton.contentWidth \* 0.5 backButton.y = itemSelected.y + itemSelected.contentHeight + backButton.contentHeight group:insert( backButton ) -- Listen for tableView events local function tableViewListener( event ) local phase = event.phase print( "Event.phase is:", event.phase ) end -- Handle row rendering local function onRowRender( event ) local phase = event.phase local row = event.row local rowTitle = display.newText( row, "Row " .. row.index, 0, 0, nil, 14 ) rowTitle.x = row.x - ( row.contentWidth \* 0.5 ) + ( rowTitle.contentWidth \* 0.5 ) rowTitle.y = row.contentHeight \* 0.5 rowTitle:setTextColor( 0, 0, 0 ) end -- Handle row updates local function onRowUpdate( event ) local phase = event.phase local row = event.row --print( row.index, ": is now onscreen" ) end -- Handle touches on the row local function onRowTouch( event ) local phase = event.phase local row = event.target if "release" == phase then --Update the item selected text itemSelected.text = "You selected item " .. row.index --Transition out the list, transition in the item selected text and the back button transition.to( tableView, { x = - tableView.contentWidth, time = 400, transition = easing.outExpo } ) transition.to( itemSelected, { x = display.contentCenterX, time = 400, transition = easing.outExpo } ) transition.to( backButton, { x = display.contentCenterX, time = 400, transition = easing.outQuad } ) end end -- Create a tableView tableView = widget.newTableView { top = 32, width = 320, height = 400, listener = tableViewListener, onRowRender = onRowRender, onRowUpdate = onRowUpdate, onRowTouch = onRowTouch, } group:insert( tableView ) -- Create 100 rows for i = 1, 25 do local isCategory = false local rowHeight = 40 local rowColor = { default = { 255, 255, 255 }, over = { 30, 144, 255 }, } local lineColor = { 220, 220, 220 } -- Make some rows categories -- if i == 25 or i == 50 or i == 75 then -- if i%5 == 0 then isCategory = true rowHeight = 24 rowColor = { default = { 150, 160, 180, 200 }, } -- end -- Insert the row into the tableView tableView:insertRow { isCategory = isCategory, rowHeight = rowHeight, rowColor = rowColor, lineColor = lineColor, } end end scene:addEventListener( "createScene" ) return scene

Hi @yosu,

Is it your intention to make every row into a “category”? I see you’ve commented out the conditional statements that would make just a few rows into categories. Also, can you try putting in an “overColor” color table in the place where you set the properties for a category row?

Thanks,

Brent

Dear Brent,

All items were put in ‘category’ so the issue can be seen easily, as it appears to be so. The missing items could not be selected anymore. In my actual codes, all the items are in ‘category’ so the user can select which ‘category’ to reveal.

I have tried to include in the ‘over’ color in the sample code with some items not in category, and here is how it looks like when fast-scrolling.

Thanks

if i%2 == 0 then isCategory = true rowHeight = 24 -- rowColor = { default = { 150, 160, 180, 200 }, } rowColor = { default={ 230, 230, 230, 255 }, over={ 150, 150, 150, 100 } } end

Hi @yosu,

I confirmed this issue on my side, and have brought it to the attention of engineering.

Thanks,

Brent

Dear Brent,

Thanks. I think it would be better to implement scrollView for this tableView. It solves all these issues. That is what I did as a work-around  for this  issue. 

Dear Yosu, 

I took the liberty to enter your bug in the Widget bugs list

https://docs.google.com/spreadsheet/ccc?key=0AsuRVbWElS3YdGpCN0V3emtmWnlwQmRUOVlpb3RkOGc&usp=sharing

Can you kindly update the row with the bug id and the initial date you filed it? Thank you very much! 

I dont know if I am filing the same bug. But it would be too obvious of an error if you run the following code

main.lua

local widget = require(“widget”)

local catCount = 0

local itemCount = 0

local function thisOnRowRender (event  )

    print(event.row.id)

    local textParams = {

        parent = event.row,

        text = "text ",

        x = 0,

        y = 0,

        font = native.systemFont,

        fontSize = 20

    }

    if event.row.isCategory then

        textParams.text = "Category  " … textParams.text … catCount

        catCount = catCount + 1

    else

        textParams.text = "Item  " … textParams.text … itemCount

        itemCount = itemCount + 1

    end

    local thisText = display.newText( textParams )

    thisText:setTextColor(255)

    thisText.x = event.row.width * .5

    thisText.y = event.row.height * .5

    thisText:toFront()

end

local function thisOnRowTouch ( event )

    – body

end

local thisTableViewParams = {

        id = “something”,

        left = 20,

        top = 20,

        width = display.viewableContentWidth,

        height = display.viewableContentHeight,

        backgroundColor = { 125, 125, 75, 255},

        hideBackground = false,

        noLines = false,

        onRowRender = thisOnRowRender,

        onRowTouch = thisOnRowTouch,

    }

local thisTableView = widget.newTableView( thisTableViewParams )

for catIterator= 1, 8 do

        

        local thisRowCreationParams = {

                rowHeight = 45,

                rowColor = {

                    default = { 15, 15, 15, 20} ,

                    over = { 75, 75, 158, 167}

                },

                lineColor = {15, 25, 40, 18},

                isCategory = true,

            }

        thisTableView:insertRow( thisRowCreationParams)

        local numberOfDisplayRows = catIterator + 1

        local displayRowsIterator = 1

        while (displayRowsIterator <= numberOfDisplayRows) do

            local thisRowCreationParams = {

                rowHeight = 30,

                rowColor = {

                    default = { 115, 115, 115, 200} ,

                    over = { 75, 175, 58, 67}

                },

                lineColor = {145, 125, 240, 128},

                isCategory = false,

            }

            thisTableView:insertRow( thisRowCreationParams)

            displayRowsIterator = displayRowsIterator + 1

        end

end

And please see the console print as well as values when this is scrolled over

I am sorry to come on it again. But I am finding it hard to acknowledge a mistake on my part

Below is a simple table view, that is all it is. It has got ‘n’ categories and each category ‘i’ have got ‘i+1’ items. as simple as that

Had it not been for colors and texts this would have been only a few lines

But here I am passing stuff by ‘params’ and can’t figure out what I am doing wrong…

local widget = require(“widget”)

local function thisOnRowRender (event  )

    local thisRow = event.row

    print(thisRow.id)

    local textParams = {

        parent = event.row,

        text = "Category " … thisRow.params.catIndex … "  Item  " … thisRow.params.itemIndex,

        x = 0,

        y = 0,

        font = native.systemFont,

        fontSize = 20

    }

    local thisText = display.newText( textParams )

    thisText:setTextColor(255)

    thisText.x = event.row.width * .5

    thisText.y = event.row.height * .5

    thisText:toFront()

end

local function thisOnRowTouch ( event )

    – body

end

local thisTableViewParams = {

        id = “something”,

        left = 20,

        top = 20,

        width = display.viewableContentWidth,

        height = display.viewableContentHeight,

        backgroundColor = { 125, 125, 75, 255},

        hideBackground = false,

        noLines = false,

        onRowRender = thisOnRowRender,

        onRowTouch = thisOnRowTouch,

    }

local thisTableView = widget.newTableView( thisTableViewParams )

for catIterator= 1, 8 do

        local thisRowDataParams = {

            catIndex = catIterator,

            itemIndex = 0

        }

        local thisRowCreationParams = {

                rowHeight = 45,

                rowColor = {

                    default = { 15, 15, 15, 20} ,

                    over = { 75, 75, 158, 167}

                },

                lineColor = {15, 25, 40, 18},

                params = thisRowDataParams,

                isCategory = true,

            }

        thisTableView:insertRow( thisRowCreationParams)

        local numberOfDisplayRows = catIterator + 1

        local displayRowsIterator = 1

        while (displayRowsIterator <= numberOfDisplayRows) do

            

            local thisRowDataParams = {

                catIndex = catIterator,

                itemIndex = displayRowsIterator

            }

            local thisRowCreationParams = {

                rowHeight = 30,

                rowColor = {

                    default = { 115, 115, 115, 200} ,

                    over = { 75, 175, 58, 67}

                },

                lineColor = {145, 125, 240, 128},

                isCategory = false,

                params = thisRowDataParams,

            }

            thisTableView:insertRow( thisRowCreationParams)

            displayRowsIterator = displayRowsIterator + 1

        end

end

you just have to paste is and see console print.

Hi @yosu,

Is it your intention to make every row into a “category”? I see you’ve commented out the conditional statements that would make just a few rows into categories. Also, can you try putting in an “overColor” color table in the place where you set the properties for a category row?

Thanks,

Brent

Dear Brent,

All items were put in ‘category’ so the issue can be seen easily, as it appears to be so. The missing items could not be selected anymore. In my actual codes, all the items are in ‘category’ so the user can select which ‘category’ to reveal.

I have tried to include in the ‘over’ color in the sample code with some items not in category, and here is how it looks like when fast-scrolling.

Thanks

if i%2 == 0 then isCategory = true rowHeight = 24 -- rowColor = { default = { 150, 160, 180, 200 }, } rowColor = { default={ 230, 230, 230, 255 }, over={ 150, 150, 150, 100 } } end

Hi @yosu,

I confirmed this issue on my side, and have brought it to the attention of engineering.

Thanks,

Brent

Dear Brent,

Thanks. I think it would be better to implement scrollView for this tableView. It solves all these issues. That is what I did as a work-around  for this  issue. 

Dear Yosu, 

I took the liberty to enter your bug in the Widget bugs list

https://docs.google.com/spreadsheet/ccc?key=0AsuRVbWElS3YdGpCN0V3emtmWnlwQmRUOVlpb3RkOGc&usp=sharing

Can you kindly update the row with the bug id and the initial date you filed it? Thank you very much! 

I dont know if I am filing the same bug. But it would be too obvious of an error if you run the following code

main.lua

local widget = require(“widget”)

local catCount = 0

local itemCount = 0

local function thisOnRowRender (event  )

    print(event.row.id)

    local textParams = {

        parent = event.row,

        text = "text ",

        x = 0,

        y = 0,

        font = native.systemFont,

        fontSize = 20

    }

    if event.row.isCategory then

        textParams.text = "Category  " … textParams.text … catCount

        catCount = catCount + 1

    else

        textParams.text = "Item  " … textParams.text … itemCount

        itemCount = itemCount + 1

    end

    local thisText = display.newText( textParams )

    thisText:setTextColor(255)

    thisText.x = event.row.width * .5

    thisText.y = event.row.height * .5

    thisText:toFront()

end

local function thisOnRowTouch ( event )

    – body

end

local thisTableViewParams = {

        id = “something”,

        left = 20,

        top = 20,

        width = display.viewableContentWidth,

        height = display.viewableContentHeight,

        backgroundColor = { 125, 125, 75, 255},

        hideBackground = false,

        noLines = false,

        onRowRender = thisOnRowRender,

        onRowTouch = thisOnRowTouch,

    }

local thisTableView = widget.newTableView( thisTableViewParams )

for catIterator= 1, 8 do

        

        local thisRowCreationParams = {

                rowHeight = 45,

                rowColor = {

                    default = { 15, 15, 15, 20} ,

                    over = { 75, 75, 158, 167}

                },

                lineColor = {15, 25, 40, 18},

                isCategory = true,

            }

        thisTableView:insertRow( thisRowCreationParams)

        local numberOfDisplayRows = catIterator + 1

        local displayRowsIterator = 1

        while (displayRowsIterator <= numberOfDisplayRows) do

            local thisRowCreationParams = {

                rowHeight = 30,

                rowColor = {

                    default = { 115, 115, 115, 200} ,

                    over = { 75, 175, 58, 67}

                },

                lineColor = {145, 125, 240, 128},

                isCategory = false,

            }

            thisTableView:insertRow( thisRowCreationParams)

            displayRowsIterator = displayRowsIterator + 1

        end

end

And please see the console print as well as values when this is scrolled over

I am sorry to come on it again. But I am finding it hard to acknowledge a mistake on my part

Below is a simple table view, that is all it is. It has got ‘n’ categories and each category ‘i’ have got ‘i+1’ items. as simple as that

Had it not been for colors and texts this would have been only a few lines

But here I am passing stuff by ‘params’ and can’t figure out what I am doing wrong…

local widget = require(“widget”)

local function thisOnRowRender (event  )

    local thisRow = event.row

    print(thisRow.id)

    local textParams = {

        parent = event.row,

        text = "Category " … thisRow.params.catIndex … "  Item  " … thisRow.params.itemIndex,

        x = 0,

        y = 0,

        font = native.systemFont,

        fontSize = 20

    }

    local thisText = display.newText( textParams )

    thisText:setTextColor(255)

    thisText.x = event.row.width * .5

    thisText.y = event.row.height * .5

    thisText:toFront()

end

local function thisOnRowTouch ( event )

    – body

end

local thisTableViewParams = {

        id = “something”,

        left = 20,

        top = 20,

        width = display.viewableContentWidth,

        height = display.viewableContentHeight,

        backgroundColor = { 125, 125, 75, 255},

        hideBackground = false,

        noLines = false,

        onRowRender = thisOnRowRender,

        onRowTouch = thisOnRowTouch,

    }

local thisTableView = widget.newTableView( thisTableViewParams )

for catIterator= 1, 8 do

        local thisRowDataParams = {

            catIndex = catIterator,

            itemIndex = 0

        }

        local thisRowCreationParams = {

                rowHeight = 45,

                rowColor = {

                    default = { 15, 15, 15, 20} ,

                    over = { 75, 75, 158, 167}

                },

                lineColor = {15, 25, 40, 18},

                params = thisRowDataParams,

                isCategory = true,

            }

        thisTableView:insertRow( thisRowCreationParams)

        local numberOfDisplayRows = catIterator + 1

        local displayRowsIterator = 1

        while (displayRowsIterator <= numberOfDisplayRows) do

            

            local thisRowDataParams = {

                catIndex = catIterator,

                itemIndex = displayRowsIterator

            }

            local thisRowCreationParams = {

                rowHeight = 30,

                rowColor = {

                    default = { 115, 115, 115, 200} ,

                    over = { 75, 175, 58, 67}

                },

                lineColor = {145, 125, 240, 128},

                isCategory = false,

                params = thisRowDataParams,

            }

            thisTableView:insertRow( thisRowCreationParams)

            displayRowsIterator = displayRowsIterator + 1

        end

end

you just have to paste is and see console print.

Hey guys,

This got fixed in 2013.2109.

Thanks,

alex

I tested with 2013.2109. However “params” is still null in “onRowRender” when isCategory is set to true in insertRow.

Can you kindly post some code for better understanding? Thanks much!!!

Run the following code and it will throw error saying that params is nil when isCategory is true.

[lua]–

local widget = require( “widget” )

– hide device status bar
display.setStatusBar( display.HiddenStatusBar )

function onRowRender(event)
local myText = display.newText(
event.row,
event.row.params.text,
100,
10,
native.systemFont,
16 )
myText:setFillColor( 1, 0, 0 )
end

local tableView = widget.newTableView
{
left = 0,
top = 0,
height = display.contentHeight,
width = display.contentWidth,
onRowRender = onRowRender,
onRowTouch = onRowTouch,
listener = scrollListener,
noLines = true
}

– Insert 40 rows
for i = 1, 40 do

local isCategory = false
local rowHeight = 36
local rowColor = { default={ 1, 1, 1 }, over={ 1, 0.5, 0, 0.2 } }
local lineColor = { 0.5, 0.5, 0.5 }

– Make some rows categories
if ( i == 1 or i == 21 ) then
isCategory = true
rowHeight = 40
rowColor = { default={ 0.8, 0.8, 0.8, 0.8 } }
lineColor = { 1, 0, 0 }
end

– Insert a row into the tableView
tableView:insertRow(
{
isCategory = isCategory,
rowHeight = rowHeight,
rowColor = rowColor,
lineColor = lineColor,
params = { text = “Row” … i }
}
)
end

[/lua]

This is a known bug: 27439.  You can check to see if params is nil before trying to access it to keep it from crashing, but you should be allowed send params to category rows as well.

Rob