tableView, newSwitch UI issue

I have an app that contains a list of newSwitch (checkbox style) entries in a tableView widget. However when I choose one of the entries and proceed to scroll the tableView to where the newSwitch is off the screen, the checkbox disappears, it is however still selected and the entry is still entered in upon submission. This happens in both iOS and Android. I have attached some code, maybe I am just approaching this from the wrong angle.

*cheers

This code just registers that the newSwitch is selected

 -- Handle press events for the checkbox local function onSwitchPress( event ) local switch = event.target if switch.isOn == false then itemID = string.gsub(itemID, "---" .. tostring(switch.id), "") elseif switch.isOn == true then itemID = itemID .. "---" .. tostring(switch.id) end end

This code displays the newSwitch and tableView

--- newSwitch Widget local onOffSwitch = widget.newSwitch { left = 250, top = 200, style = "checkbox", id = dataId, onPress = onSwitchPress, } onOffSwitch.x = display.contentWidth - 50 onOffSwitch.y = row.height / 1.9 row:insert(onOffSwitch) --- tableView widget local tableView = widget.newTableView { backgroundColor = {0}, hideBackground = true, top = 15, left = 10, width = display.contentWidth - 20, height = display.contentHeight - 170, onRowRender = onRowRender, onRowTouch = onRowTouch, listener = scrollListener } for i = 1, maxRows do tableView:insertRow { rowHeight = 50, isCategory = false, rowColor = { default = { 255, 255, 255, 0 } }, lineColor = { default = { 0.90, 0.90, 0.90 } } } end group:insert(tableView)

Hi @dailydosha,

I don’t see your “onRowRender()” function in the code above. Are you creating the switch inside there and inserting it into the row that was just rendered?

Brent

Hello, thank you for the quick reply. Yes I am, the onRowRender function looks like this:

local function onRowRender( event ) local row = event.row local id = row.index local dataId = data.data[id].id ...... a bunch of other stuff local onOffSwitch = widget.newSwitch { left = 250, top = 200, style = "checkbox", id = dataId, onPress = onSwitchPress, } onOffSwitch.x = display.contentWidth - 50 onOffSwitch.y = row.height / 1.9 row:insert(onOffSwitch) deleteArrow:addEventListener( "touch", onRowDelResults ) return true end

Hmmm… what do you mean by “the checkbox disappears”? You mean the object is completely gone, or its “state” (checked or not) does not stay the same when it comes back into view?

Its “state” (when checked) does not stay the same when it comes back into view.

Thanks for your help :slight_smile:

Ah yes, now I see what’s going on. This one catches people unaware sometimes.

Basically, when you have something like a checkbox or some other object which should “change state” in a TableView, you should set a property of the row params at the time the switch is manipulated. This is because the row data (params) is what remains “known” to the TableView when rows go in and out of view, and thus they can be tracked when the row comes back into view.

To address this in your case, you’ll basically have to do 2 things:

  1. Within your “onRowRender()” function, after you create the switch, assign the row’s ID to that object (the switch). Also, set a property in the row params telling the switch state. Finally, write a conditional block to set the swtich state when it’s first rendered or when it comes back into view. For example:

[lua]

onOffSwitch.rowID = row.id

row.params.isSwitchOn = onOffSwitch.isOn  – “.isOn” is a property of all switches to get their current state

if ( row.params.isSwitchOn == true ) then

    onOffSwitch:setState( { isOn=true } )

else

    onOffSwitch:setState( { isOn=false } )

end

[/lua]

  1. In your switch handling function (“onSwitchPress()”), get the row reference based on the switch’s “rowID” property (the first part of step #1). Then, based on the new state of the switch, set the “isSwitchOn” parameter to true or false.

[lua]

local function onSwitchPress( event )

    local switch = event.target

    local thisRow = tableView:getRowAtIndex( switch.rowID )

    if switch.isOn == false then

        thisRow.params.isSwitchOn = false

    else

        thisRow.params.isSwitchOn = true

    end

[/lua]

Brent

IMPORTANT:

  1. You should read this doc which pertains to the “.isOn” state of the switch and which type of listener you’re using (“onPress” or “onRelease”). Currently you’re using “onPress” but you might want to change that. Basically, depending on which listener style you’re using in the switch constructor, the results might be totally opposite of what you expect (so this clarifies what is actually happening):

https://docs.coronalabs.com/api/type/SwitchWidget/isOn.html

  1. For proper Lua scoping, you’ll need to forward-reference your TableView object so that it’s known to the “onSwitchPress()” function.

I have done what you suggested but have been unable to solve the issue. I am attaching my file ‘gen_lists.lua’, if you or anyone has the opportunity to take a look and can suggest where I need to change my code, it will be greatly appreciated. 

Thank you for your help!

Try with onOffSwitch.isOn=row.params.isSwitchOn

Thank you this fixed the issue.

*cheers! :slight_smile:

Hi @dailydosha,

I don’t see your “onRowRender()” function in the code above. Are you creating the switch inside there and inserting it into the row that was just rendered?

Brent

Hello, thank you for the quick reply. Yes I am, the onRowRender function looks like this:

local function onRowRender( event ) local row = event.row local id = row.index local dataId = data.data[id].id ...... a bunch of other stuff local onOffSwitch = widget.newSwitch { left = 250, top = 200, style = "checkbox", id = dataId, onPress = onSwitchPress, } onOffSwitch.x = display.contentWidth - 50 onOffSwitch.y = row.height / 1.9 row:insert(onOffSwitch) deleteArrow:addEventListener( "touch", onRowDelResults ) return true end

Hmmm… what do you mean by “the checkbox disappears”? You mean the object is completely gone, or its “state” (checked or not) does not stay the same when it comes back into view?

Its “state” (when checked) does not stay the same when it comes back into view.

Thanks for your help :slight_smile:

Ah yes, now I see what’s going on. This one catches people unaware sometimes.

Basically, when you have something like a checkbox or some other object which should “change state” in a TableView, you should set a property of the row params at the time the switch is manipulated. This is because the row data (params) is what remains “known” to the TableView when rows go in and out of view, and thus they can be tracked when the row comes back into view.

To address this in your case, you’ll basically have to do 2 things:

  1. Within your “onRowRender()” function, after you create the switch, assign the row’s ID to that object (the switch). Also, set a property in the row params telling the switch state. Finally, write a conditional block to set the swtich state when it’s first rendered or when it comes back into view. For example:

[lua]

onOffSwitch.rowID = row.id

row.params.isSwitchOn = onOffSwitch.isOn  – “.isOn” is a property of all switches to get their current state

if ( row.params.isSwitchOn == true ) then

    onOffSwitch:setState( { isOn=true } )

else

    onOffSwitch:setState( { isOn=false } )

end

[/lua]

  1. In your switch handling function (“onSwitchPress()”), get the row reference based on the switch’s “rowID” property (the first part of step #1). Then, based on the new state of the switch, set the “isSwitchOn” parameter to true or false.

[lua]

local function onSwitchPress( event )

    local switch = event.target

    local thisRow = tableView:getRowAtIndex( switch.rowID )

    if switch.isOn == false then

        thisRow.params.isSwitchOn = false

    else

        thisRow.params.isSwitchOn = true

    end

[/lua]

Brent

IMPORTANT:

  1. You should read this doc which pertains to the “.isOn” state of the switch and which type of listener you’re using (“onPress” or “onRelease”). Currently you’re using “onPress” but you might want to change that. Basically, depending on which listener style you’re using in the switch constructor, the results might be totally opposite of what you expect (so this clarifies what is actually happening):

https://docs.coronalabs.com/api/type/SwitchWidget/isOn.html

  1. For proper Lua scoping, you’ll need to forward-reference your TableView object so that it’s known to the “onSwitchPress()” function.

I have done what you suggested but have been unable to solve the issue. I am attaching my file ‘gen_lists.lua’, if you or anyone has the opportunity to take a look and can suggest where I need to change my code, it will be greatly appreciated. 

Thank you for your help!

Try with onOffSwitch.isOn=row.params.isSwitchOn

Thank you this fixed the issue.

*cheers! :slight_smile: