As everybody else using the Corona SDK I have a hard time using textFields. They don’t behave like (other) widgets and all kinds of hacks has to be deployed. The Corona implementation of this kind of suck, but I’ll limit my complaints for now.
I’m trying to have a set of textFields contained in a scroll view. To do this I have a runtime listener making sure that the y pos of the textFields follows the scrollView position. This works (even if the slight lagging makes it look a bit jelly-like).
When the user touches the textField, this is picked up in the input event listener as a “began” phase event. Here I calculate a new scroll position to make sure this particular textField is moved above the keyboard. Again, this seems to work ok.
The problem is when the editing is done.
I can intercept the both the “ended” and “submitted” phase in the input event listener and then move the scrollView back to the pre-keyboard position (if the textField loses focus or the user hits ENTER on the keyboard). This also works well - unless the user hits the ENTER key…
Because when the user hits the ENTER key, the textField never loses focus. And that means that the next time the user touches it, it will never enter the “began” phase.
So if the following happens:
-
User edits field (it,s moved to make way for the keyboard)
-
User scrolls about making the field being placed low in the screen
-
User edits field again
This will not make the field scroll up, because “began” is never reached.
So, is there a clever way to handle this? Is there a way to remove the focus from a textField so that the next time the user touches it the “began” phase is activated?
A working (or rather non-working) example is below:
local widget = require( "widget" ) local noKeyScrPos = 0 local LINE\_1\_Y\_POS = 800 local inputText = nil -- Create the scroll widget local scrollView = widget.newScrollView { x = display.contentWidth/2, y = display.contentHeight/2, width = display.contentWidth, height = display.contentHeight, scrollHeight = 4000, horizontalScrollDisabled = true, hideBackground = true, } -- Give the scrollView a scroll value that ensures the visibility of yPos local function MakeSpaceForKeyboard(yPos) local x, noKeyScrPos = scrollView:getContentPosition() -- Save current (no keyboard) scroll pos local scrollPos = display.contentHeight/2 - yPos -- Calc new scroll pos to make way for the keyboard if (scrollPos + yPos \< 100) then scrollPos = 100 end scrollView:scrollToPosition { y = scrollPos, time = 250 } -- Apply new scroll value end -- Create widgets local label = display.newText("Label:", 50, LINE\_1\_Y\_POS, native.systemFont, 28) label.anchorX = 0 scrollView:insert(label) local function inputListener(event) if ( event.phase == "began" ) then MakeSpaceForKeyboard(LINE\_1\_Y\_POS) -- When the editing starts make way for the keyboard elseif (event.phase == "ended") then scrollView:scrollToPosition { y = noKeyScrPos, time = 250 } -- When ending the editing, move back to pre-keyboard pos end end -- Input field inputText = native.newTextField(display.contentWidth-50, LINE\_1\_Y\_POS, 150, 72 ) inputText:addEventListener( "userInput", inputListener ) inputText.font = native.newFont( native.systemFont, 18 ) inputText.anchorX = 1 inputText.inputType = "number" inputText.startY = LINE\_1\_Y\_POS -- Make sure the native text fields scrolls with the scrollView local frameRedrawListener = function(e) local x, y = scrollView:getContentPosition() inputText.y = LINE\_1\_Y\_POS + y end Runtime:addEventListener( "enterFrame", frameRedrawListener )