Scrollview inside tableView rows... how to pass focus?

SImilar to the use case in another thread here… Buttons or other objects in each tableView row. When you move up or down more than 10px need to pass focus back to the tableView but seems like takeFocus only exist in scrollView. How would you handle these cases? Typical use case could be the Delete button in a row.

In my case I wanted to see if I can put in a horizontal scrollView into a tableView to simulate the functionality of say Apple IOS App Store running on your iPad. You know the one with table rows with different categories of apps and then the row itself containing icons/names of apps in a horizontal scrollview.

Well, I see that scrollView in a tableView works great! I don’t know if there are any limitations which might bite me but so far my experimentation using CL Sample ListView3 + some scrollView action is working real well. 

Only problem is how to pass back focus from scrollView to tableView if the movement is vertical.  Seems like takeFocus() is not available for some reason on tableView. Any other way to achieve what I need to do? Thanks much in advance for your help.

Here’s the code I have so far getting the scrollView to work inside the tableView in case anyone is interested. I am excited about the possibilities here. Right now the only way you can move the tableView rows vertically if is you click on the narrow edges on left or right and then move. The row itself as it houses the scrollView allows horizontal scrolling. The trick is to get the vertical scroll events passed from scrollView into the tableView. I appreciate any suggestions you might have. Thanks

display.setStatusBar( display.HiddenStatusBar ) -- Import the widget library local widget = require( "widget" ) -- create a constant for the left spacing of the row content local LEFT\_PADDING = 10 --Set the background to white display.setDefault( "background", 1, 1, 1 ) --Create a group to hold our widgets & images local widgetGroup = display.newGroup() -- Create a background to go behind our tableView local background = display.newImage( widgetGroup, "bg.jpg", 0, 0, true ) background.anchorX = 0; background.anchorY = 0 -- TopLeft anchor -- The gradient used by the title bar local titleGradient = { type = 'gradient', color1 = { 189/255, 203/255, 220/255, 255/255 }, color2 = { 89/255, 116/255, 152/255, 255/255 }, direction = "down" } -- Create toolbar to go at the top of the screen local titleBar = display.newRect( display.contentCenterX, 0, display.contentWidth, 32 ) titleBar:setFillColor( titleGradient ) titleBar.y = display.screenOriginY + titleBar.contentHeight \* 0.5 -- create embossed text to go on toolbar local titleText = display.newEmbossedText( "My List", display.contentCenterX, titleBar.y, native.systemFontBold, 20 ) -- create a shadow underneath the titlebar (for a nice touch) local shadow = display.newImage( "shadow.png" ) shadow.anchorX = 0; shadow.anchorY = 0 -- TopLeft anchor shadow.x, shadow.y = 0, titleBar.y + titleBar.contentHeight \* 0.5 shadow.xScale = 320 / shadow.contentWidth shadow.alpha = 0.45 --Text to show which item we selected local itemSelected = display.newText( "You selected item ", 0, 0, native.systemFontBold, 28 ) itemSelected.x = display.contentWidth + itemSelected.contentWidth \* 0.5 itemSelected.y = display.contentCenterY widgetGroup:insert( itemSelected ) -- Forward reference for our back button & tableview local backButton, list -- Our ScrollView listener local function scrollListener( event ) local phase = event.phase local direction = event.direction if "began" == phase then --print( "Began" ) elseif "moved" == phase then --print( "Moved" ) local dy = math.abs( ( event.y - event.yStart ) ) -- If our finger has moved more than the desired range if dy \> 10 then -- Pass the focus back to the scrollView list:takeFocus( event ) end elseif "ended" == phase then --print( "Ended" ) end -- If the scrollView has reached it's scroll limit if event.limitReached then if "up" == direction then print( "Reached Top Limit" ) elseif "down" == direction then print( "Reached Bottom Limit" ) elseif "left" == direction then print( "Reached Left Limit" ) elseif "right" == direction then print( "Reached Right Limit" ) end end return true end -- Handle row rendering local function onRowRender( event ) local phase = event.phase local row = event.row -- in graphics 2.0, the group contentWidth / contentHeight are initially 0, and expand once elements are inserted into the group. -- in order to use contentHeight properly, we cache the variable before inserting objects into the group local groupContentHeight = row.contentHeight --local rowTitle = display.newText( row, "List item " .. row.index, 0, 0, native.systemFontBold, 16 ) -- Create a ScrollView local scrollView = widget.newScrollView { left = 0, top = 0, width = row.width - 20, height = row.height - 4, --bottomPadding = 50, id = "onBottom", scrollWidth = row.width \* 3, horizontalScrollDisabled = false, verticalScrollDisabled = true, listener = scrollListener, } row:insert( scrollView ) -- in Graphics 2.0, the row.x is the center of the row, no longer the top left. scrollView.x = LEFT\_PADDING -- we also set the anchorX of the text to 0, so the object is x-anchored at the left scrollView.anchorX = 0 scrollView.anchorY = 0 scrollView.y = 0 local lotsOfText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur imperdiet consectetur euismod. Phasellus non ipsum vel eros vestibulum consequat. Integer convallis quam id urna tristique eu viverra risus eleifend.\n\nAenean suscipit placerat venenatis. Pellentesque faucibus venenatis eleifend. Nam lorem felis, rhoncus vel rutrum quis, tincidunt in sapien. Proin eu elit tortor. Nam ut mauris pellentesque justo vulputate convallis eu vitae metus. Praesent mauris eros, hendrerit ac convallis vel, cursus quis sem. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque fermentum, dui in vehicula dapibus, lorem nisi placerat turpis, quis gravida elit lectus eget nibh. Mauris molestie auctor facilisis.\n\nCurabitur lorem mi, molestie eget tincidunt quis, blandit a libero. Cras a lorem sed purus gravida rhoncus. Cras vel risus dolor, at accumsan nisi. Morbi sit amet sem purus, ut tempor mauris.\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur imperdiet consectetur euismod. Phasellus non ipsum vel eros vestibulum consequat. Integer convallis quam id urna tristique eu viverra risus eleifend.\n\nAenean suscipit placerat venenatis. Pellentesque faucibus venenatis eleifend. Nam lorem felis, rhoncus vel rutrum quis, tincidunt in sapien. Proin eu elit tortor. Nam ut mauris pellentesque justo vulputate convallis eu vitae metus. Praesent mauris eros, hendrerit ac convallis vel, cursus quis sem. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque fermentum, dui in vehicula dapibus, lorem nisi placerat turpis, quis gravida elit lectus eget nibh. Mauris molestie auctor facilisis.\n\nCurabitur lorem mi, molestie eget tincidunt quis, blandit a libero. Cras a lorem sed purus gravida rhoncus. Cras vel risus dolor, at accumsan nisi. Morbi sit amet sem purus, ut tempor mauris. " --Create a text object containing the large text string and insert it into the scrollView local lotsOfTextObject = display.newText( lotsOfText, display.contentCenterX, 0, 300, 0, "Helvetica", 14) lotsOfTextObject:setFillColor( 0 ) lotsOfTextObject.anchorY = 0.0 -- Top --------------------------------lotsOfTextObject:setReferencePoint( display.TopCenterReferencePoint ) lotsOfTextObject.y = titleText.y + titleText.contentHeight + 10 scrollView:insert( lotsOfTextObject ) end -- Hande row touch events local function onRowTouch( event ) local phase = event.phase local row = event.target if "press" == phase then print( "Pressed row: " .. row.index ) elseif "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 -- The table x origin refers to the center of the table in Graphics 2.0, so we translate with half the object's contentWidth transition.to( list, { x = - list.contentWidth \* 0.5, time = 400, transition = easing.outExpo } ) transition.to( itemSelected, { x = display.contentCenterX, time = 400, transition = easing.outExpo } ) transition.to( backButton, { alpha = 1, time = 400, transition = easing.outQuad } ) print( "Tapped and/or Released row: " .. row.index ) end end -- Create a tableView list = widget.newTableView { top = 38, width = 320, height = 448, hideBackground = true, --maskFile = "mask-320x448.png", onRowRender = onRowRender, onRowTouch = onRowTouch, } --Insert widgets/images into a group widgetGroup:insert( list ) widgetGroup:insert( titleBar ) widgetGroup:insert( titleText ) widgetGroup:insert( shadow ) --Handle the back button release event local function onBackRelease() --Transition in the list, transition out the item selected text and the back button -- The table x origin refers to the center of the table in Graphics 2.0, so we translate with half the object's contentWidth transition.to( list, { x = list.contentWidth \* 0.5, time = 400, transition = easing.outExpo } ) transition.to( itemSelected, { x = display.contentWidth + itemSelected.contentWidth \* 0.5, time = 400, transition = easing.outExpo } ) transition.to( backButton, { alpha = 0, time = 400, transition = easing.outQuad } ) end --Create the back button backButton = widget.newButton { width = 298, height = 56, label = "Back", labelYOffset = - 1, onRelease = onBackRelease } backButton.alpha = 0 backButton.x = display.contentCenterX backButton.y = display.contentHeight - backButton.contentHeight widgetGroup:insert( backButton ) ---[[\*\*Remove This\*\* -- insert rows into list (tableView widget) for i = 1, 3 do list:insertRow { rowHeight = 150, rowColor = { default = { 1, 1, 1, 0 }, }, } end --]]

Any ideas? Is this not possible? Thanks!

Here’s the code I have so far getting the scrollView to work inside the tableView in case anyone is interested. I am excited about the possibilities here. Right now the only way you can move the tableView rows vertically if is you click on the narrow edges on left or right and then move. The row itself as it houses the scrollView allows horizontal scrolling. The trick is to get the vertical scroll events passed from scrollView into the tableView. I appreciate any suggestions you might have. Thanks

display.setStatusBar( display.HiddenStatusBar ) -- Import the widget library local widget = require( "widget" ) -- create a constant for the left spacing of the row content local LEFT\_PADDING = 10 --Set the background to white display.setDefault( "background", 1, 1, 1 ) --Create a group to hold our widgets & images local widgetGroup = display.newGroup() -- Create a background to go behind our tableView local background = display.newImage( widgetGroup, "bg.jpg", 0, 0, true ) background.anchorX = 0; background.anchorY = 0 -- TopLeft anchor -- The gradient used by the title bar local titleGradient = { type = 'gradient', color1 = { 189/255, 203/255, 220/255, 255/255 }, color2 = { 89/255, 116/255, 152/255, 255/255 }, direction = "down" } -- Create toolbar to go at the top of the screen local titleBar = display.newRect( display.contentCenterX, 0, display.contentWidth, 32 ) titleBar:setFillColor( titleGradient ) titleBar.y = display.screenOriginY + titleBar.contentHeight \* 0.5 -- create embossed text to go on toolbar local titleText = display.newEmbossedText( "My List", display.contentCenterX, titleBar.y, native.systemFontBold, 20 ) -- create a shadow underneath the titlebar (for a nice touch) local shadow = display.newImage( "shadow.png" ) shadow.anchorX = 0; shadow.anchorY = 0 -- TopLeft anchor shadow.x, shadow.y = 0, titleBar.y + titleBar.contentHeight \* 0.5 shadow.xScale = 320 / shadow.contentWidth shadow.alpha = 0.45 --Text to show which item we selected local itemSelected = display.newText( "You selected item ", 0, 0, native.systemFontBold, 28 ) itemSelected.x = display.contentWidth + itemSelected.contentWidth \* 0.5 itemSelected.y = display.contentCenterY widgetGroup:insert( itemSelected ) -- Forward reference for our back button & tableview local backButton, list -- Our ScrollView listener local function scrollListener( event ) local phase = event.phase local direction = event.direction if "began" == phase then --print( "Began" ) elseif "moved" == phase then --print( "Moved" ) local dy = math.abs( ( event.y - event.yStart ) ) -- If our finger has moved more than the desired range if dy \> 10 then -- Pass the focus back to the scrollView list:takeFocus( event ) end elseif "ended" == phase then --print( "Ended" ) end -- If the scrollView has reached it's scroll limit if event.limitReached then if "up" == direction then print( "Reached Top Limit" ) elseif "down" == direction then print( "Reached Bottom Limit" ) elseif "left" == direction then print( "Reached Left Limit" ) elseif "right" == direction then print( "Reached Right Limit" ) end end return true end -- Handle row rendering local function onRowRender( event ) local phase = event.phase local row = event.row -- in graphics 2.0, the group contentWidth / contentHeight are initially 0, and expand once elements are inserted into the group. -- in order to use contentHeight properly, we cache the variable before inserting objects into the group local groupContentHeight = row.contentHeight --local rowTitle = display.newText( row, "List item " .. row.index, 0, 0, native.systemFontBold, 16 ) -- Create a ScrollView local scrollView = widget.newScrollView { left = 0, top = 0, width = row.width - 20, height = row.height - 4, --bottomPadding = 50, id = "onBottom", scrollWidth = row.width \* 3, horizontalScrollDisabled = false, verticalScrollDisabled = true, listener = scrollListener, } row:insert( scrollView ) -- in Graphics 2.0, the row.x is the center of the row, no longer the top left. scrollView.x = LEFT\_PADDING -- we also set the anchorX of the text to 0, so the object is x-anchored at the left scrollView.anchorX = 0 scrollView.anchorY = 0 scrollView.y = 0 local lotsOfText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur imperdiet consectetur euismod. Phasellus non ipsum vel eros vestibulum consequat. Integer convallis quam id urna tristique eu viverra risus eleifend.\n\nAenean suscipit placerat venenatis. Pellentesque faucibus venenatis eleifend. Nam lorem felis, rhoncus vel rutrum quis, tincidunt in sapien. Proin eu elit tortor. Nam ut mauris pellentesque justo vulputate convallis eu vitae metus. Praesent mauris eros, hendrerit ac convallis vel, cursus quis sem. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque fermentum, dui in vehicula dapibus, lorem nisi placerat turpis, quis gravida elit lectus eget nibh. Mauris molestie auctor facilisis.\n\nCurabitur lorem mi, molestie eget tincidunt quis, blandit a libero. Cras a lorem sed purus gravida rhoncus. Cras vel risus dolor, at accumsan nisi. Morbi sit amet sem purus, ut tempor mauris.\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur imperdiet consectetur euismod. Phasellus non ipsum vel eros vestibulum consequat. Integer convallis quam id urna tristique eu viverra risus eleifend.\n\nAenean suscipit placerat venenatis. Pellentesque faucibus venenatis eleifend. Nam lorem felis, rhoncus vel rutrum quis, tincidunt in sapien. Proin eu elit tortor. Nam ut mauris pellentesque justo vulputate convallis eu vitae metus. Praesent mauris eros, hendrerit ac convallis vel, cursus quis sem. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque fermentum, dui in vehicula dapibus, lorem nisi placerat turpis, quis gravida elit lectus eget nibh. Mauris molestie auctor facilisis.\n\nCurabitur lorem mi, molestie eget tincidunt quis, blandit a libero. Cras a lorem sed purus gravida rhoncus. Cras vel risus dolor, at accumsan nisi. Morbi sit amet sem purus, ut tempor mauris. " --Create a text object containing the large text string and insert it into the scrollView local lotsOfTextObject = display.newText( lotsOfText, display.contentCenterX, 0, 300, 0, "Helvetica", 14) lotsOfTextObject:setFillColor( 0 ) lotsOfTextObject.anchorY = 0.0 -- Top --------------------------------lotsOfTextObject:setReferencePoint( display.TopCenterReferencePoint ) lotsOfTextObject.y = titleText.y + titleText.contentHeight + 10 scrollView:insert( lotsOfTextObject ) end -- Hande row touch events local function onRowTouch( event ) local phase = event.phase local row = event.target if "press" == phase then print( "Pressed row: " .. row.index ) elseif "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 -- The table x origin refers to the center of the table in Graphics 2.0, so we translate with half the object's contentWidth transition.to( list, { x = - list.contentWidth \* 0.5, time = 400, transition = easing.outExpo } ) transition.to( itemSelected, { x = display.contentCenterX, time = 400, transition = easing.outExpo } ) transition.to( backButton, { alpha = 1, time = 400, transition = easing.outQuad } ) print( "Tapped and/or Released row: " .. row.index ) end end -- Create a tableView list = widget.newTableView { top = 38, width = 320, height = 448, hideBackground = true, --maskFile = "mask-320x448.png", onRowRender = onRowRender, onRowTouch = onRowTouch, } --Insert widgets/images into a group widgetGroup:insert( list ) widgetGroup:insert( titleBar ) widgetGroup:insert( titleText ) widgetGroup:insert( shadow ) --Handle the back button release event local function onBackRelease() --Transition in the list, transition out the item selected text and the back button -- The table x origin refers to the center of the table in Graphics 2.0, so we translate with half the object's contentWidth transition.to( list, { x = list.contentWidth \* 0.5, time = 400, transition = easing.outExpo } ) transition.to( itemSelected, { x = display.contentWidth + itemSelected.contentWidth \* 0.5, time = 400, transition = easing.outExpo } ) transition.to( backButton, { alpha = 0, time = 400, transition = easing.outQuad } ) end --Create the back button backButton = widget.newButton { width = 298, height = 56, label = "Back", labelYOffset = - 1, onRelease = onBackRelease } backButton.alpha = 0 backButton.x = display.contentCenterX backButton.y = display.contentHeight - backButton.contentHeight widgetGroup:insert( backButton ) ---[[\*\*Remove This\*\* -- insert rows into list (tableView widget) for i = 1, 3 do list:insertRow { rowHeight = 150, rowColor = { default = { 1, 1, 1, 0 }, }, } end --]]

Any ideas? Is this not possible? Thanks!

ksan,

i have the same issue to pass takefocus() to tableveiw from the overlay rectangle… i am trying to do swipe with tabs applicaiton … here is my post :

http://forums.coronalabs.com/topic/52360-how-to-create-swipe-views-with-tabs/#entry274797

I am not able to pass vertical swipe back to the table view… 

regards

Abdul

I sort of gave up on Corona SDK for this sort of thing. Sorry for not having an answer. Best of luck to you.

I would use two scrollview’s, not a scrollview inside a tableview.

ksan :slight_smile: … i already started to learn android sdk for the same issue …

 

horacebury

i am not using scrollviews at all. i am using table view in different scenes… on top of that i am trying to use your tick of rectangle… 

I understand. My statement is more about the reasons for using each class rather than how.

The tableview is a specific implementation of the scrollview for particular use cases and not a top-level class like the scrollview, hence the lack of the takeFocus function.

Ideally, if you want to build an App Store style interface you would be using nested scrollviews and managing the locations/existence of items yourself.

ksan,

i have the same issue to pass takefocus() to tableveiw from the overlay rectangle… i am trying to do swipe with tabs applicaiton … here is my post :

http://forums.coronalabs.com/topic/52360-how-to-create-swipe-views-with-tabs/#entry274797

I am not able to pass vertical swipe back to the table view… 

regards

Abdul

I sort of gave up on Corona SDK for this sort of thing. Sorry for not having an answer. Best of luck to you.

I would use two scrollview’s, not a scrollview inside a tableview.

ksan :slight_smile: … i already started to learn android sdk for the same issue …

 

horacebury

i am not using scrollviews at all. i am using table view in different scenes… on top of that i am trying to use your tick of rectangle… 

I understand. My statement is more about the reasons for using each class rather than how.

The tableview is a specific implementation of the scrollview for particular use cases and not a top-level class like the scrollview, hence the lack of the takeFocus function.

Ideally, if you want to build an App Store style interface you would be using nested scrollviews and managing the locations/existence of items yourself.