How to have a native text field inside of a scrollview

Anyone? I need to know how to do this!?!?

Hi Summit Tech,

Can you add a “print” line for the “phase” in your ScrollView listener and confirm that the phase names are what you expect, as you move the scroll view around?

Brent

Ok, it did not print when my scroll was supposed to happen, but my other prints were shown.

OK, thanks. Please check the conditional logic a bit more and see if you can get it all working. It seems that the basic code was fine, except for a tiny logic error.

Regards,

Brent

Ok, thanks for the help! My scroll view listener logic is fixed :slight_smile:

Unfortunately, however, I am now in a pickle.

In my scroll code, I call a function that occurs below (showFakeText1) which causes and error.

So I move it above the listener code. Now that just creates another problem. In that code I add a rectangle to my scroll view… before it even exists. So I put my scroll view declaration above the showFakeText1 function, which is inheritly above the scroll view listeners which is not allowed.

Any fix for this puzzling problem?

Thanks

Summit Tech

Hi Summit Tech,

Yes, the joy of scoping. :slight_smile:

You can probably solve this by up-referencing the lower function, and write it slightly different in syntax (just the opening line of the lower function) as follows:

[lua]

local lowerFunction

local function scrollListener( event )

   …

end

lowerFunction = function()

   …

end

[/lua]

In this way, the function “lowerFunction” is still local, but your listener function “scrollListener” can refer to it (despite it residing below) because you’ve up-referenced it above the listener function. Give this a try and see how it works for you…

Regards,

Brent

Great thanks for all the help!

If anyone needs code then just post below! I will be glad to give you mine!

I’d love to see the final functional version of the code if you are willing to share. This is a problem I have wrestled with for a long time, mainly trying to make a universal textField “replacer” so I don’t have to have individual functions for each of the textFields on the page.

Me too. Thank you so much for your willingness to share.

Of course guys!
I am more than willing to share, after I get back from vacation.
Some credit would be awesome!

----------------------------------------------------------------------------------------- -- -- main.lua --Saving user input ----------------------------------------------------------------------------------------- local json = require ("json") local widget = require( "widget" ) display.setStatusBar( display.HiddenStatusBar ) --Vars --For text field local inputFontSize = 18 local inputFontHeight = 30 local tHeight = 60 --global vars local justStarted = true --First text box local defaultField local fakeTextOutside local fakeTextInside local showingFakeBox = true local text1 = "Name" local faketext1 --Second text box local fieldTwo local fakeTextOutside2 local fakeTextInside2 local showingFakeBox2 = true local text2 = "Username" local faketext2 --Third text box local fieldThree local fakeTextOutside3 local fakeTextInside3 local showingFakeBox3 = true local text3 = "Password" local faketext3 --For Display local testText = "Use?" --scene that will always be showing bg = display.newRect(0,0,display.contentWidth,display.contentHeight) bg:setFillColor(0,200,250) title = display.newText("Save Input",display.contentWidth/4, 30, system.defaultFont, 64) title:setTextColor(0,0,0) --Functions local showFakeText1 local showFakeText2 local showFakeText3 local function fieldHandler( textField ) return function( event ) if ( "began" == event.phase ) then -- This is the "keyboard has appeared" event -- In some cases you may want to adjust the interface when the keyboard appears. elseif ( "ended" == event.phase ) then -- This event is called when the user stops editing a field: for example, when they touch a different field if showingFakeBox == false then text1 = textField().text showingFakeBox = true showFakeText1() elseif showingFakeBox2 == false then text2 = textField().text showingFakeBox2 = true showFakeText2() elseif showingFakeBox3 == false then text3 = textField().text showingFakeBox3 = true showFakeText3() end elseif ( "editing" == event.phase ) then elseif ( "submitted" == event.phase ) then -- This event occurs when the user presses the "return" key (if available) on the onscreen keyboard -- Hide keyboard native.setKeyboardFocus( nil ) end end end --Scroll View local function scrollListener( event ) local phase = event.phase end -- Create a ScrollView local scrollView = widget.newScrollView { left = 10, top = 150, width = 620, height = 950, id = "onBottom", hideBackground = true, horizontalScrollingDisabled = true, verticalScrollingDisabled = false, maskFile = "assets/scrollViewMask-350.png", listener = scrollListener, } --[[Insert an image into the scrollView local background = display.newImageRect( "assets/scrollimage.jpg", 768, 1024 ) background.x = background.contentWidth \* 0.5 background.y = background.contentHeight \* 0.5 scrollView:insert( background )]]-- local function radioSwitchListener( event ) --when radioButton is changed do this end -- Create some text to label the radio button with local radioButtonText = display.newText( testText, 220, 190, native.systemFont, 66 ) radioButtonText:setTextColor( 0 ) scrollView:insert( radioButtonText ) -- Create a default radio button (using widget.setTheme) local radioButton = widget.newSwitch { left = 25, top = 180, width = 100, height = 100, style = "radio", id = "Radio Button", initialSwitchState = true, onPress = radioSwitchListener, } scrollView:insert( radioButton ) local otherRadioButton = widget.newSwitch { left = 115, top = 180, width = 100, height = 100, style = "radio", id = "Radio Button2", initialSwitchState = false, onPress = radioSwitchListener, } scrollView:insert( otherRadioButton ) --------- --First --------- local function showRealText1(event) print ("function showRealText1") justStarted = false if showingFakeBox == true then print(justStarted) showingFakeBox = false end --[[if text1 ~= "" then fakeText1:removeSelf() end]] defaultField = native.newTextField( 107, 640, 300, tHeight+6 ) defaultField.font = native.newFont( native.systemFontBold, inputFontSize ) defaultField:addEventListener( "userInput", fieldHandler( function() return defaultField end ) ) fakeTextOutside:removeSelf() fakeTextInside:removeSelf() end showFakeText1 = function(event) print ("function showFakeText1") if showingFakeBox == true then if justStarted == false then defaultField:removeSelf() end end fakeTextOutside = display.newRect(100-4,490,300,tHeight+6) fakeTextOutside:setFillColor(150,150,150) fakeTextInside = display.newRect(100,494,300-8,tHeight-2) scrollView:insert( fakeTextOutside ) scrollView:insert( fakeTextInside ) if text1 ~= "" then fakeText1 = display.newText(text1, fakeTextInside.x - 140, fakeTextInside.y -30, native.systemFontBold,36) fakeText1:setTextColor(0,0,0) scrollView:insert(fakeText1) if justStarted == true then fakeText1:setTextColor(200,200,200) elseif justStarted == false then fakeText1:setTextColor(0,0,0) end end fakeTextInside:addEventListener("touch", showRealText1) end ---------- --Second ---------- local function showRealText2(event) print ("function showRealText2") justStarted = false if showingFakeBox2 == true then print(justStarted) showingFakeBox2 = false end if text2 ~= "" then fakeText2:removeSelf() end fieldTwo = native.newTextField( 107, 740, 300, tHeight+6 ) fieldTwo.font = native.newFont( native.systemFontBold, inputFontSize ) fieldTwo:addEventListener( "userInput", fieldHandler( function() return fieldTwo end ) ) fakeTextOutside2:removeSelf() fakeTextInside2:removeSelf() end showFakeText2 = function(event) print ("function showFakeText2") if showingFakeBox2 == true then if justStarted == false then print("2!!!!!") fieldTwo:removeSelf() end end fakeTextOutside2 = display.newRect(100-4,590,300,tHeight+6) fakeTextOutside2:setFillColor(150,150,150) fakeTextInside2 = display.newRect(100,594,300-8,tHeight-2) scrollView:insert( fakeTextOutside2 ) scrollView:insert( fakeTextInside2 ) if text2 ~= "" then fakeText2 = display.newText(text2, fakeTextInside2.x - 140, fakeTextInside2.y -30, native.systemFontBold,36) scrollView:insert(fakeText2) if justStarted == true then fakeText2:setTextColor(200,200,200) elseif justStarted == false then fakeText2:setTextColor(0,0,0) end end fakeTextInside2:addEventListener("touch", showRealText2) end ----------- --Third ----------- local function showRealText3(event) print ("function showRealText3") justStarted = false if showingFakeBox3 == true then print(justStarted) showingFakeBox3 = false end if text3 ~= "" then fakeText3:removeSelf() end fieldThree = native.newTextField( 107, 840, 300, tHeight+6 ) fieldThree.font = native.newFont( native.systemFontBold, inputFontSize ) fieldThree:addEventListener( "userInput", fieldHandler( function() return fieldThree end ) ) fieldThree.isSecure = true fakeTextOutside3:removeSelf() fakeTextInside3:removeSelf() end showFakeText3 = function(event) print ("function showFakeText3") if showingFakeBox3 == true then if justStarted == false then print("3!!!!!") fieldThree:removeSelf() end end fakeTextOutside3 = display.newRect(100-4,690,300,tHeight+6) fakeTextOutside3:setFillColor(150,150,150) fakeTextInside3 = display.newRect(100,694,300-8,tHeight-2) scrollView:insert( fakeTextOutside3 ) scrollView:insert( fakeTextInside3 ) if text3 ~= "" then fakeText3 = display.newText(text3, fakeTextInside3.x - 140, fakeTextInside3.y -30, native.systemFontBold,36) scrollView:insert(fakeText3) if justStarted == true then fakeText3:setTextColor(200,200,200) elseif justStarted == false then fakeText3:setTextColor(0,0,0) end end fakeTextInside3:addEventListener("touch", showRealText3) end showFakeText1() showFakeText2() showFakeText3()

Please note that this is ALL my code not just fake textfield :wink:

Enjoy!

Really cool of you to share that; you should put it in the code exchange! Something that others should see for sure.

I’d love to see the final functional version of the code if you are willing to share. This is a problem I have wrestled with for a long time, mainly trying to make a universal textField “replacer” so I don’t have to have individual functions for each of the textFields on the page.

Me too. Thank you so much for your willingness to share.

Of course guys!
I am more than willing to share, after I get back from vacation.
Some credit would be awesome!

----------------------------------------------------------------------------------------- -- -- main.lua --Saving user input ----------------------------------------------------------------------------------------- local json = require ("json") local widget = require( "widget" ) display.setStatusBar( display.HiddenStatusBar ) --Vars --For text field local inputFontSize = 18 local inputFontHeight = 30 local tHeight = 60 --global vars local justStarted = true --First text box local defaultField local fakeTextOutside local fakeTextInside local showingFakeBox = true local text1 = "Name" local faketext1 --Second text box local fieldTwo local fakeTextOutside2 local fakeTextInside2 local showingFakeBox2 = true local text2 = "Username" local faketext2 --Third text box local fieldThree local fakeTextOutside3 local fakeTextInside3 local showingFakeBox3 = true local text3 = "Password" local faketext3 --For Display local testText = "Use?" --scene that will always be showing bg = display.newRect(0,0,display.contentWidth,display.contentHeight) bg:setFillColor(0,200,250) title = display.newText("Save Input",display.contentWidth/4, 30, system.defaultFont, 64) title:setTextColor(0,0,0) --Functions local showFakeText1 local showFakeText2 local showFakeText3 local function fieldHandler( textField ) return function( event ) if ( "began" == event.phase ) then -- This is the "keyboard has appeared" event -- In some cases you may want to adjust the interface when the keyboard appears. elseif ( "ended" == event.phase ) then -- This event is called when the user stops editing a field: for example, when they touch a different field if showingFakeBox == false then text1 = textField().text showingFakeBox = true showFakeText1() elseif showingFakeBox2 == false then text2 = textField().text showingFakeBox2 = true showFakeText2() elseif showingFakeBox3 == false then text3 = textField().text showingFakeBox3 = true showFakeText3() end elseif ( "editing" == event.phase ) then elseif ( "submitted" == event.phase ) then -- This event occurs when the user presses the "return" key (if available) on the onscreen keyboard -- Hide keyboard native.setKeyboardFocus( nil ) end end end --Scroll View local function scrollListener( event ) local phase = event.phase end -- Create a ScrollView local scrollView = widget.newScrollView { left = 10, top = 150, width = 620, height = 950, id = "onBottom", hideBackground = true, horizontalScrollingDisabled = true, verticalScrollingDisabled = false, maskFile = "assets/scrollViewMask-350.png", listener = scrollListener, } --[[Insert an image into the scrollView local background = display.newImageRect( "assets/scrollimage.jpg", 768, 1024 ) background.x = background.contentWidth \* 0.5 background.y = background.contentHeight \* 0.5 scrollView:insert( background )]]-- local function radioSwitchListener( event ) --when radioButton is changed do this end -- Create some text to label the radio button with local radioButtonText = display.newText( testText, 220, 190, native.systemFont, 66 ) radioButtonText:setTextColor( 0 ) scrollView:insert( radioButtonText ) -- Create a default radio button (using widget.setTheme) local radioButton = widget.newSwitch { left = 25, top = 180, width = 100, height = 100, style = "radio", id = "Radio Button", initialSwitchState = true, onPress = radioSwitchListener, } scrollView:insert( radioButton ) local otherRadioButton = widget.newSwitch { left = 115, top = 180, width = 100, height = 100, style = "radio", id = "Radio Button2", initialSwitchState = false, onPress = radioSwitchListener, } scrollView:insert( otherRadioButton ) --------- --First --------- local function showRealText1(event) print ("function showRealText1") justStarted = false if showingFakeBox == true then print(justStarted) showingFakeBox = false end --[[if text1 ~= "" then fakeText1:removeSelf() end]] defaultField = native.newTextField( 107, 640, 300, tHeight+6 ) defaultField.font = native.newFont( native.systemFontBold, inputFontSize ) defaultField:addEventListener( "userInput", fieldHandler( function() return defaultField end ) ) fakeTextOutside:removeSelf() fakeTextInside:removeSelf() end showFakeText1 = function(event) print ("function showFakeText1") if showingFakeBox == true then if justStarted == false then defaultField:removeSelf() end end fakeTextOutside = display.newRect(100-4,490,300,tHeight+6) fakeTextOutside:setFillColor(150,150,150) fakeTextInside = display.newRect(100,494,300-8,tHeight-2) scrollView:insert( fakeTextOutside ) scrollView:insert( fakeTextInside ) if text1 ~= "" then fakeText1 = display.newText(text1, fakeTextInside.x - 140, fakeTextInside.y -30, native.systemFontBold,36) fakeText1:setTextColor(0,0,0) scrollView:insert(fakeText1) if justStarted == true then fakeText1:setTextColor(200,200,200) elseif justStarted == false then fakeText1:setTextColor(0,0,0) end end fakeTextInside:addEventListener("touch", showRealText1) end ---------- --Second ---------- local function showRealText2(event) print ("function showRealText2") justStarted = false if showingFakeBox2 == true then print(justStarted) showingFakeBox2 = false end if text2 ~= "" then fakeText2:removeSelf() end fieldTwo = native.newTextField( 107, 740, 300, tHeight+6 ) fieldTwo.font = native.newFont( native.systemFontBold, inputFontSize ) fieldTwo:addEventListener( "userInput", fieldHandler( function() return fieldTwo end ) ) fakeTextOutside2:removeSelf() fakeTextInside2:removeSelf() end showFakeText2 = function(event) print ("function showFakeText2") if showingFakeBox2 == true then if justStarted == false then print("2!!!!!") fieldTwo:removeSelf() end end fakeTextOutside2 = display.newRect(100-4,590,300,tHeight+6) fakeTextOutside2:setFillColor(150,150,150) fakeTextInside2 = display.newRect(100,594,300-8,tHeight-2) scrollView:insert( fakeTextOutside2 ) scrollView:insert( fakeTextInside2 ) if text2 ~= "" then fakeText2 = display.newText(text2, fakeTextInside2.x - 140, fakeTextInside2.y -30, native.systemFontBold,36) scrollView:insert(fakeText2) if justStarted == true then fakeText2:setTextColor(200,200,200) elseif justStarted == false then fakeText2:setTextColor(0,0,0) end end fakeTextInside2:addEventListener("touch", showRealText2) end ----------- --Third ----------- local function showRealText3(event) print ("function showRealText3") justStarted = false if showingFakeBox3 == true then print(justStarted) showingFakeBox3 = false end if text3 ~= "" then fakeText3:removeSelf() end fieldThree = native.newTextField( 107, 840, 300, tHeight+6 ) fieldThree.font = native.newFont( native.systemFontBold, inputFontSize ) fieldThree:addEventListener( "userInput", fieldHandler( function() return fieldThree end ) ) fieldThree.isSecure = true fakeTextOutside3:removeSelf() fakeTextInside3:removeSelf() end showFakeText3 = function(event) print ("function showFakeText3") if showingFakeBox3 == true then if justStarted == false then print("3!!!!!") fieldThree:removeSelf() end end fakeTextOutside3 = display.newRect(100-4,690,300,tHeight+6) fakeTextOutside3:setFillColor(150,150,150) fakeTextInside3 = display.newRect(100,694,300-8,tHeight-2) scrollView:insert( fakeTextOutside3 ) scrollView:insert( fakeTextInside3 ) if text3 ~= "" then fakeText3 = display.newText(text3, fakeTextInside3.x - 140, fakeTextInside3.y -30, native.systemFontBold,36) scrollView:insert(fakeText3) if justStarted == true then fakeText3:setTextColor(200,200,200) elseif justStarted == false then fakeText3:setTextColor(0,0,0) end end fakeTextInside3:addEventListener("touch", showRealText3) end showFakeText1() showFakeText2() showFakeText3()

Please note that this is ALL my code not just fake textfield :wink:

Enjoy!

Really cool of you to share that; you should put it in the code exchange! Something that others should see for sure.

Is there a way to limit the scroll view to a certain area of the screen so it does not scroll over the page header of the app screen?

Hi @app.help,

Yes, you can do this by masking the scroll view with a mask image. This is described in the documentation here:

http://docs.coronalabs.com/api/library/widget/newScrollView.html

Be sure to read the details on how to properly create a mask (specific pixel multiples, border around, etc.). The link to the Masking guide is located in the same document above.

Best regards,

Brent Sorrentino

Thank you.  I was able to get that fixed, but when I click the back button to go to the previous screen (storyboard scene) everything within the scrollView stays on the screen.