Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

How to have a native text field inside of a scrollview
Started by Summit Tech Jun 06 2013 06:24 AM

- - - - -
24 replies to this topic
text textfield widget scroll scrollview
[TOPIC CONTROLS]
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

Summit Tech

[GLOBAL: userInfoPane.html]
Summit Tech
  • Basic
  • PipPipPipPipPipPip
  • 123 posts
  • Jedi

Hey everyone!

Quick but important question.

 

I am creating a scroll view using the widgets library. Inside the scroll view I place a radio button (which scrolls properly) and a text field that does not. 

 

I have inserted my textField into the scroll view, but it does not work.

Here is my code for the textField

 

defaultField = native.newTextField( 100, 490, 300, tHeight )
defaultField.font = native.newFont( native.systemFontBold, inputFontSize )
defaultField:addEventListener( "userInput", fieldHandler( function() return defaultField end ) ) 
scrollView:insert( defaultField )

 

Any help would be greatly appreciated!



[TOPIC: post.html]
#2

Tom

[GLOBAL: userInfoPane.html]
Tom
  • Corona Staff
  • 1,387 posts
  • Jedi

There are limitations with native display objects. They are always on top of other display objects and they can not be added to groups. You could create a fake textField using display.newRect and display.newText and bring up a real native.textField when the rect is touched.



[TOPIC: post.html]
#3

Summit Tech

[GLOBAL: userInfoPane.html]
Summit Tech
  • Basic
  • PipPipPipPipPipPip
  • 123 posts
  • Jedi

Thanks for the help!

I managed to create both a textField and a fake text field (2 rects)

However I have having difficulty going from real to fake.

When the user click the two rectangles it turns into a text box, however when I scroll the scrollView I get an error.

Which function should I put the change from real to fake in?



[TOPIC: post.html]
#4

Summit Tech

[GLOBAL: userInfoPane.html]
Summit Tech
  • Basic
  • PipPipPipPipPipPip
  • 123 posts
  • Jedi

Does anybody have any code examples for creating a faux text box?



[TOPIC: post.html]
#5

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Corona Staff
  • 9,566 posts
  • Jedi

Use display.newText() to create the text on screen that you want.  Then create your native.newTextField() in an off screen location.  Then in the event handler's "editing" phase do something like:

 

 
     if event.phase == "editing" then
           textOnScreen.text = textFieldOffScreen.text
     end

 

This if course assumes you named your two text fields "textOnScreen" and "textFieldOffScreen", adapt as necessary.

 

You might also want to have a small rectangle to act like a cursor and in that "editing" phase, position it just after the textOnScreen.width.



[TOPIC: post.html]
#6

carlostg

[GLOBAL: userInfoPane.html]
carlostg
  • Pro
  • PipPip
  • 11 posts
  • Member

Rob, do you mean placing the TextField offscreen like this?

 

When the TextField is out of the screen this does not work but if placed at y=479 it does work.

 

Can you explain how to make it work off screen?

 

Thanks,

Carlos

 

local bg = display.newRect(0, 0, 320, 480)
bg:setFillColor(255,255,255)
 
local myTextField
 
local function onMyTextField(event)
    if event.phase == "began" then
        print(event.phase)
        local function onTF(event)
            local phase = event.phase
            local target = event.target
 
            if phase == "editing" then
                myTextField.text = target.text
                myTextField:setReferencePoint(display.CenterLeftReferencePoint)
                myTextField.x = 5
            end
        end
        local offTF = native.newTextField(0, 480, 320, 20)
        offTF:addEventListener( "userInput", onTF )
        timer.performWithDelay(100, function() native.setKeyboardFocus(offTF) end, 1)
    end
end
myTextField = display.newText("Click to enter text", 5, 50, native.systemFont, 14)
myTextField:setTextColor(0,0,0)
myTextField:addEventListener("touch", onMyTextField)



[TOPIC: post.html]
#7

Summit Tech

[GLOBAL: userInfoPane.html]
Summit Tech
  • Basic
  • PipPipPipPipPipPip
  • 123 posts
  • Jedi

Ok so here is my code...


--Scroll View
local function scrollListener( event )
	if event.phase == "beganScroll" then
defaultField:removeSelf()
		end
				
		return true
	end

  local function showRealText1(event) 
   if showingFakeBox == true then
  showingFakeBox = false
end
defaultField = native.newTextField( 107, 640, 300, tHeight+6 )
defaultField.font = native.newFont( native.systemFontBold, inputFontSize )
defaultField:addEventListener( "userInput", fieldHandler( function() return defaultField end ) ) 

  
end




local function showFakeText1(event)
  if showingFakeBox == true then
    if justStarted == false then
   defaultField:removeSelf()
    end
  faked1 = false
  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 )

fakeTextInside:addEventListener("touch", showRealText1)
justStarted = false
end

 

Note- I did not include nor make the text replacement as I could do that with ease.

 

When I click on the fake text box, the real one appears but is not in editing mode, so another click is required to edit. (This might be a problem for the user, but I do not think there is any possible solutions for this problem.)

 

The "real" problem is when my scroll view starts to move, I try to remove the real text field, but it does not work.

 

Any help would be much appreciated.

 

Summit Tech



[TOPIC: post.html]
#8

Summit Tech

[GLOBAL: userInfoPane.html]
Summit Tech
  • Basic
  • PipPipPipPipPipPip
  • 123 posts
  • Jedi

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



[TOPIC: post.html]
#9

Brent Sorrentino

[GLOBAL: userInfoPane.html]
Brent Sorrentino
  • Corona Staff
  • 4,330 posts
  • Jedi

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



[TOPIC: post.html]
#10

Summit Tech

[GLOBAL: userInfoPane.html]
Summit Tech
  • Basic
  • PipPipPipPipPipPip
  • 123 posts
  • Jedi

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



[TOPIC: post.html]
#11

Brent Sorrentino

[GLOBAL: userInfoPane.html]
Brent Sorrentino
  • Corona Staff
  • 4,330 posts
  • Jedi

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



[TOPIC: post.html]
#12

Summit Tech

[GLOBAL: userInfoPane.html]
Summit Tech
  • Basic
  • PipPipPipPipPipPip
  • 123 posts
  • Jedi

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

 

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



[TOPIC: post.html]
#13

Brent Sorrentino

[GLOBAL: userInfoPane.html]
Brent Sorrentino
  • Corona Staff
  • 4,330 posts
  • Jedi

Hi Summit Tech,

Yes, the joy of scoping. :)

 

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:

 

local lowerFunction
 
local function scrollListener( event )
   ...
end
 
lowerFunction = function()
   ...
end

 

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



[TOPIC: post.html]
#14

Summit Tech

[GLOBAL: userInfoPane.html]
Summit Tech
  • Basic
  • PipPipPipPipPipPip
  • 123 posts
  • Jedi

Great thanks for all the help!

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



[TOPIC: post.html]
#15

se_nperryman

[GLOBAL: userInfoPane.html]
se_nperryman
  • Starter
  • PipPipPip
  • 44 posts
  • Advanced Member

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.



[TOPIC: post.html]
#16

ksan

[GLOBAL: userInfoPane.html]
ksan
  • Pro
  • PipPipPipPipPipPip
  • 2,694 posts
  • Jedi

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

[TOPIC: post.html]
#17

Summit Tech

[GLOBAL: userInfoPane.html]
Summit Tech
  • Basic
  • PipPipPipPipPipPip
  • 123 posts
  • Jedi

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

[TOPIC: post.html]
#18

Summit Tech

[GLOBAL: userInfoPane.html]
Summit Tech
  • Basic
  • PipPipPipPipPipPip
  • 123 posts
  • Jedi

-----------------------------------------------------------------------------------------
--
-- 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 ;)

 

Enjoy!



[TOPIC: post.html]
#19

se_nperryman

[GLOBAL: userInfoPane.html]
se_nperryman
  • Starter
  • PipPipPip
  • 44 posts
  • Advanced Member

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



[TOPIC: post.html]
#20

app.help

[GLOBAL: userInfoPane.html]
app.help
  • Pro
  • Pip
  • 3 posts
  • Newbie

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?



[TOPIC: post.html]
#21

Brent Sorrentino

[GLOBAL: userInfoPane.html]
Brent Sorrentino
  • Corona Staff
  • 4,330 posts
  • Jedi

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



[TOPIC: post.html]
#22

app.help

[GLOBAL: userInfoPane.html]
app.help
  • Pro
  • Pip
  • 3 posts
  • Newbie

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.  



[TOPIC: post.html]
#23

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Corona Staff
  • 9,566 posts
  • Jedi

You have to add your scrollView or tableView to the scene's group just like you would any other display object.



[TOPIC: post.html]
#24

app.help

[GLOBAL: userInfoPane.html]
app.help
  • Pro
  • Pip
  • 3 posts
  • Newbie

Are there any general pdf documents or pdf manuals available on Corona/lua programming offered by Corona?  I am new to Corona, and am currently teaching myself based off our previous app's code, and online forums.  



[TOPIC: post.html]
#25

Brent Sorrentino

[GLOBAL: userInfoPane.html]
Brent Sorrentino
  • Corona Staff
  • 4,330 posts
  • Jedi

Hi @app.help,

 

There are many learning resources and guides located in Corona University. Most new users begin with these resources to get a foundational understanding of the SDK, then move on the API documentation for more specific details.

http://www.coronalabs.com/resources/tutorials/getting-started-with-corona/

 

If you're looking for an actual book, there are many offerings located in our "Books and Courses" section here:

http://www.coronalabs.com/resources/books/

 

Hope this helps,

Brent Sorrentino




[topic_controls]
[/topic_controls]



Also tagged with one or more of these keywords: text, textfield, widget, scroll, scrollview