is it possible to control newTextField for character limitation ?

Hi Team,

can we control the length of characters that allowed to be entered in the newTextField  ?

can we make newTextField read only ?

Thanks

Abdul

You would have to make it by your own… or just use the atanas widget (http://forums.coronalabs.com/topic/42977-widgetneweditfield-beta-testers-needed/page-4#entry228827

+1 for newEditField… All you have to do is throw a maxChars = 10, etc in the constructor.

thanks all for your responses, 

I am trying to add newEditField but still not successful… i have posted a question in the widgetstown forum about the issue I am facing. generally i see it as very promising  :slight_smile:

Thanks

Abdul

I’ve got some keyboard entry stuff you can look at. It has a couple references to some utility functions I use (like utils.isAndroid, or utils.isSimulator) that you can pretty easily find in the forums if you want to adapt the idea.

Although it’s intended as a reference – it works (with G2.0), and the strategy is to A) never have native fields on the screen (except while actually editing), and B) use a centralized editing routine that will callback specific app code when the user is done (so the user can use a non-native text object when editing is done).

With this strategy, (rounded) rectangles are used to lay out where your entry fields will be (and take the initial tap event), and display.newText objects represent your fields when not in the process of editing (on top of the rounded rectangles). So – when not editing, everything is a standard display object / plays nicely with transitions, tableViews, etc… (a source of many headaches, if you have native fields onscreen all the time).

Once the user taps a rectangle input field area (remember, you put listeners on the rectangles), your listener calls to create an editField object (basically, a temporary native field). When the user is done editing (hits enter), the editField code calls a function (you specified) back. At that point the native field is removed, the standard display.newText object is updated, and your app code can do bounds checking on numeric input, update counters, etc, as needed (and everything is back to standard objects)…

This also avoids most of the problems devs run into when trying to do offscreen text input, since the actual native input is done onscreen, totally legit from an OS standpoint (devs usually do offscreen input to avoid the problem of always having native fields onscreen / on top of other objects).

It does some other little things, like limiting input length, making a buzz noise, etc, but you’ll want to think through the overall input needs of your app, consider Coronas capabilities / limitations, and devise a strategy (such as outlined above) that will let your app jump through all the hoops it needs to regarding display, movement, editing, etc of text input fields…

Anyways… although the strategy might be somewhat sophisticated, the code maybe not so much… Hopefully there’s something here that will help you get some ideas on ways to (or not to) jump through some of the hoops

[lua]

module(…, package.seeall)

– editField.lua
– Corona SDK basic keyboard entry api…
– mpappas, 2012 – copy, share, enjoy. Throw me a credit now and then :wink:

– Ported to g2.0 2013 (needs a bit of cleanup of commented code)

– call editField.new() to create / start the keyboard entry. The overall idea is that the calling code passes in a rectangle object
– (typically the frame area for the input area), and a few parameters (type of kb, max length of entry, a callback function when done, etc).
– This code will then create a native editfield, exactly the size of the rectabgle and do text input within those bounds (at a max length as passed in, etc).
– When the user dismisses the kb, the native field is removed, and the users callback is executed so that the entry can be displayed as a non-native field,
– on top of the original rectangle (passed in).

– The code also includes a font size calculator, called once automatically to set the native font size (tricky on droid).

–   Usage example:
–           group.nicknameEditField = editField.new(group.NickNameText.text, group.NicknameBack, nicknameEditDone, “default”, false, 0, 20)

–          Where: “group” is a display group…
–                 NickNameText is a text display object, in front of…
–                 NickNameBack which is typically a white rectangle frame for the text area…
–                 nicknameEditDone is a callback function to be executed when the user dismisses the kb…

–          Note that if the user taps outside the edit field, normal user code touch handlers will still fire off. To stop any possible
–          editing that could be occuring on a screen/remove native kb, call editField.removeEditTextField() (which will remove kb/do callbacks etc if necc.)
–          Setting kb focus to nil will also trigger the end phase of text editing automatically.

local this = nil
local utils = require(“utils”)
mojoData = require(“mojodata”)

editText = “”
local tray = nil            – passed in object that sits behind the text field
callingText = nil           – calling fuinctions text field to change/alter

local editTextField = nil       – Onscreen nativeTextField(s) that corona uses for input… NOT available in simulator… booo…
local userCallBack = nil             – function to call back the user when edit is completed…

– Below is the function prototype for the keyboard handler…
local keyboardHandlerEditText


local isAndroid = “Android” == system.getInfo(“platformName”)
local isSimulator = “simulator” == system.getInfo(“environment”)
local inputFontSize = nil           – Will be calculated at runtime…
local targetFontSize = 18       – point size we shoot for, relative to an iphone 5 (scaled up for larger screens, down for smaller, relatively)
local maxEditLength = 50        – Maximum length a string can be, set in new to 2000 or some giant number, for messages…

local function calcFontSize()
    print(" – calcFontSize()")
    print("-----------------------" )    
            
    local sysType = system.getInfo(“architectureInfo”)
    print(" – sysType == “, sysType)            
    print(” – display.contentScaleY  == “, display.contentScaleY )
    print(” – display.screenOriginY  == “, display.screenOriginY )          
    
    inputFontSize = targetFontSize / display.contentScaleY    – old method is fallback (ends up being sim setting)
    local heightIn = 4
    local fontScale = 1
    
    if( utils.isAndroid == true ) then      – try and get the real width / height and deal with it            
        print(” – -- Android font size calc…")
        
        local missingInches = display.screenOriginY * -2     – account for both top and bottom area (x2), and change the sign sign since originY is always negative, if it exists…
        
        missingInches = missingInches / 320             – 320 is 1 inch, in my 640x960 virual content space (960 == 3 inches for my app, designed for a standard iphone 4 display)        
                                                        – different contentScale sizes will use a different virtual pixel / inch value (eg, 320x480 virtual content = missingInches / 160)
–        missingInches = 0       – testing… if corona compensates… then this is not needed…
        
        print(" – missing inches == “, missingInches)
        
        heightIn = system.getInfo( “androidDisplayHeightInInches” )
        local widthIn = system.getInfo( “androidDisplayWidthInInches” )
        print(” – original height == “, heightIn)
        
        heightIn = heightIn - missingInches               
     
        --Make sure its not nil… e.g. the simulator will return nil, perhaps some bad devices will too…
        if heightIn ~= nil then
            – heightIn is height of actual droid app is running on
            fontScale =  heightIn / 3.0 – 3.0 is actual iPhone 3gs /4 /4s height
            print(” – fontsize set on actual droid screen inch height")
–            print(" – widthIn = “, widthIn)
–            print(” – heightIn = “, heightIn)
        else
            fontScale = 4/3  --Default to a 4 inch diagonal (iphone is 3.0)
            print(” – fontsize set to 4 inch phone size")
        end
        
        print(" heightIn == “, heightIn)
        print(” fontScale == “, fontScale)
        inputFontSize = targetFontSize*fontScale            
    else                                    – else is iOS
        print(” – -- iOS font size calc…")
        heightIn = 3                                  – default to stnadard iPhone size        

        local missingInches = display.screenOriginY * -2    – account for both top and bottom area (x2), and change the sign sign originY is negative, if it exists…
        
        missingInches = missingInches / 320             – 320 is 1 inch, in my 640x960 virual content space (960 == 3 inches for my app, designed for a standard iphone 4 display)
                                                        – different contentScale sizes will use a different virtual pixel / inch value (eg, 320x480 virtual content = missingInches / 160)        
–        missingInches = 0       – testing… if corona compensates… then this is not needed…
        print(" – missing inches == ", missingInches)

        –
        – Since there is no corona facility to get the screen height of the device on iOS, we’ll determine it ourselves.
        –
        if( sysType == “iPhone2,1” ) then       – 3GS        
            heightIn = 3.0 - missingInches      – original iPhone size
            print(" – iPhone 3GS detected")        
        elseif( string.match(sysType, “iPhone3”) or string.match(sysType, “iPhone4”) ) then       – iPhone 4, 4S        
            heightIn = 3.0 - missingInches      – Same size as the old 3gs- better resolution, but same size
            print(" – iPhone 4 detected")        
        elseif( string.match(sysType, “iPhone5”)  ) then       – iPhone 5
            heightIn = 4.0 - missingInches      – Should go back to 3, after missing inches chopped off by corona are deducted.
            print(" – iPhone 5 detected")      – This phones screen is taller, a little… Corona will end up chopping it off though
        elseif( string.match(sysType, “iPod5”) ) then       – new, tall iPad
            heightIn = 4.0 - missingInches      – Should go back to 3, after missing inches chopped off by corona are deducted.            
        elseif sysType == “iPad2,5” or sysType == “iPad2,6” or sysType == “iPad2,7” or sysType == “iPad2,8” then    – 2,8 is unknown, just a guess at next mini #
            heightIn = 6.25 - missingInches     – mini
            print(" – iPad mini detected")     – A good amount taller. Need a much bigger point size for this device, for the input fonts to look scaled right     
        elseif( string.match(sysType, “iPad”) ) then       – standard iPad
            heightIn = 7.75 - missingInches     – iPad
            print(" – iPad detected")          – MUCH taller screen, really gonna need to scale fonts up in point size for this bad boy (or they will look less than half size for the field)            
        else
            print(" – unrecognized iOS device, using default 3.5 inches tall") – iPods will fall to here, they are 3.5 anyways…
            if( missingInches == 0 ) then
                – iPod falls through to here (and it is 3 inches tall, and any missing inches accounted for in a tall version, so that works for now)
                heightIn = 3.0 - missingInches  – I would hope this is typical, zero extra on an unknown ios device
            else
                heightIn = 4.0 - missingInches  – otherwise, we’ll take a flying guess that the unknown device is bigger than a tiny breadbox, and smaller than a car. (4 inches tall, iphone 5 format)
            end
        end        

        fontScale =  heightIn / 3.0                 – 3.0 inches is actual iPhone 4 height (that my content is based on)
        print(" heightIn == “, heightIn)
        print(” fontScale == “, fontScale)
        inputFontSize = targetFontSize*fontScale            
    end
                
    print(” – final fontsize == “, inputFontSize)
    print(”-----------------------" )    
    return inputFontSize
end

function getText()      – returns last value test set to
    return editText
end

function setText(text)      – sets value…
    editText = text
end

local function createEditTextField(keyboardType, isSecure)

    print( " – Creating EditTextField, tray ==", tray)

    if( editTextField == nil) then
                
        if( inputFontSize == nil ) then     – First timer?
            calcFontSize()                  – Determine the device native scale / font size to use
        end
        
        local tempSize = inputFontSize
        if( tray.height < 66) then                – small  tray means we use a smaller font…
            tempSize = inputFontSize * 0.9
        end        

–        local tempX = (tray.x - tray.width/2) + 10  – Crimp it in side to side
        local tempX = tray.x  – + 10  – Crimp it in side to side
        local tempW = tray.width - 10
        local tempY, tempH
        
        
        tempY = tray.y  – ios
        tempH = tray.height
        
        – following was needed in corona g1.0, seems to be fixed in g2.0
        --[[        
        if( utils.isAndroid == true ) then  – Special issue with android – font size is larger than bounding box in some cases…
                                            – Causes the text to position weird…
            tempH = tray.height * 2         – inputFontSize?? What should it equal!!!
            tempY = (tray.y - tempH/2)      – a little extra for android
            print(" – android, adjusted tray y,h")
        else
–            tempY = (tray.y - tray.height/2)  – ios
            tempY = tray.y  – ios
            tempH = tray.height
            print(" – iOS, using tray.h,w")
        end
        --]]
        
–        print(" tempH == “, tempH)
        
        if ( tempH < 42 ) then   
            tempH = 42
        end                
        
        tempX = tempX + tempW/2 – Added for graphics 2.0, all native fields init’d with center coords
        
        editTextField = native.newTextField( tempX, tempY, tempW, tempH, keyboardHandlerEditText)
        editTextField.font = native.newFont( native.systemFont, tempSize )
–        editTextField.size = tempSize
        editTextField.inputType = keyboardType
        editTextField.align = ‘left’;
        editTextField.text = editText
        editTextField.isEditable = true
        editTextField:setTextColor( 0,0,0 )        – Native field apparently still uses setTextColor, not setFillColor after g2.0 release…
–        editTextField:setFillColor( 0,0,0 )        
        editTextField.hasBackground = false     – true     – use true for debugging position of field
        editTextField.isSecure = isSecure
        print(”  editTextField created – textSize ==", tempSize)
        print(" x,y == “, editTextField.x, editTextField.y)
    else
       print(”   – editTextField ~= nil")
    end

–    print("  – Giving editTextField focus")
    native.setKeyboardFocus( editTextField )  – Get the keyboard coming onscreen…
    
    return editTextField
end

function removeEditTextField()

–    print( "  *** Deleting editTextField", userCallBack)

–        native.setKeyboardFocus( nil )                      – Tell the os to get rid of the keyboard/end the editing)

    if( editTextField ~= nil ) then
–        print(“a”)
        editText = editTextField.text                       – Set the var passed to the login server call…
–        print(“b”)        
        callingText = editText                     – sets the calling routines field…
–        editTextField:removeSelf()
        
–        print(" **** CALLERS TEXT SET TO: ", callingText)

–        editTextField:removeSelf()              – These must be manually removed, or they stay onscreen even after a screen change…
–        print(“c”)
–        print("    – editTextField removed. Calling back…")
        if( userCallBack ~= nil ) then
–            print(“d”)
            
            – Setting up a tempcallback var, in case callback creates a new field, so we dont nil it…
            local tempCallBack = utils.deepCopy(userCallBack)
            userCallBack = nil            
            tempCallBack()

–            print(“Callback completed”)
        else
            print(" – calbback == nil")
        end       
        editTextField = nil     – Finally, set it to nil        
        native.setKeyboardFocus( nil )    
        
     else
–        print("    – editTextField already was deleted.")
     end
     
–    print( "  *** removeEditTextField() done.")     

end

function keyboardHandlerEditText(event) – handles the pop up keyboard when editing

–    print("******")
–    print( " Keyboard handler editText entered – phase: “, event.phase )
–    print(” – target == ", event.target)

–    if( editTextField == nil and (event.phase ~= “ended”) ) then
–        print("  *** editTextField == nil!! drats!")
–        return true
–    end

    if (event == nil) then                                         – Don’t know why I’m seeing no event/phase sometimes (after ENDED phase)
        print(" — event == nil, exiting — event == ", event )
        return true
    end

    if (event.phase == nil) then
        print(" — event.phase == nil, exiting — event.phase == ", event.phase )
        return true
    end

    if ( event.phase == “began” ) then
–        print( "  editText event began")
–        native.setKeyboardFocus( editTextField )  – They finished editing, dismiss the keyboard
    end
    
    if( event.phase == “editing” ) then
–        print("  -event.newCharacters == “, event.newCharacters)
        if( editTextField ~= nil ) then
            if( event.newCharacters  == “\n” ) then
    –            print(” --newline detected")
                editText = editTextField.text                       – Set the var passed to the login server call…
                editTextField.isEditable = false
    –            native.setKeyboardFocus( nil )            
    –            print(" – focus set to nil")
                removeEditTextField()
            else
                if( string.len(editTextField.text) > maxEditLength ) then
                    – We need to delete the char, wherever in the string they are editing…
                    local tempText
                    
                    if( event.startPosition == 1 ) then
                        tempText = editTextField.text:sub(2, -1 )                                   – Take them all except that first one they just entered
                    elseif( event.startPosition == string.len(editTextField.text) ) then            – Take em all except the last one…               
                        tempText = editTextField.text:sub(1, string.len(editTextField.text) - 1 )   – Take them all except that first one they just entered                
                    else
                        tempText = editTextField.text:sub(1, event.startPosition-1 )                – First part…
                        tempText = tempText … editTextField.text:sub(event.startPosition+1, -1 )   – Last part…                    
                    end
                
                    editTextField.text = tempText      – editTextField.text:sub(1, string.len(editTextField.text)-1)        – remove the new char
                    audio.play( mojoData._NotifyAudio2, { channel=mojoData._sfxChannel, loops=0, fadein=0 }  )  – negative sfx
                end
            
            end
    –        utils.printTable( event, " Event", 3 )
        end
    end    
    if ( event.phase == “submitted” ) then
–        print( " Keyboard handler editText submitted detected --")
        if( editTextField ~= nil ) then     – just to be safe…        
            native.setKeyboardFocus( nil )     – ** – Tell the os to get rid of the keyboard/end the editing)
–            removeEditTextField()
            
–            print(" – Have a edit field")
        else
            print( "    editTextField == nil")
        end
    end

    if ( event.phase == “ended” ) then
        removeEditTextField()

–        print( " Keyboard handler editText ended detected --")
        if( event.target ~= nil ) then
            if( editTextField ~= nil ) then     – just to be safe…        
                – hmmm…
–                editText = editTextField.text                       – Set the var passed to the login server call…
–                removeEditTextField()       – **
            end
        else
            print( " event.target == nil" )
        end
    end

–    print("******")
   return true      – flag that we dealt with the event
end

function new (userText,back, callBack, keyboardType, isSecure, yOffset, maxLen)     – Called with the object that text sits on top of… yOffset is used if/when screen scrolls to accomodate keyboard

    print(" – new editField called… usertext == “, userText)
    print(” – yOffset == “, yOffset)
    
    if( utils.isSimulator == true ) then
        yOffset = 0  – graphics 2.0 updates the sim coords differently it seems…
    end
    
    if( maxLen == nil ) then
        maxEditLength = 2000        – A descip or a mesage can be up to this length…
    else
        maxEditLength = maxLen
    end
–    print(”  – back == ", back)

    – First make sure they weren’t already editing a different edit field…
    native.setKeyboardFocus( nil )       – Tell the os to get rid of the keyboard/end the editing)
        
–    if( tray ~= nil ) then
    if( editTextField ~= nil ) then
–        print(" – manually removing edit field in new()")
        removeEditTextField()   – Get rid of the old one…
    end
    
    editText = userText     – Use the passed in text as the basis…
    
–    print("*** Entered editField:new()")

    – set the edit fields coords to the passed in objects coords
    --tray = utils.deepCopy(back)     – Set to the passed in back object / tray the text sits on *** ONLY DEEPCOPIES A POINTER == arghhh
    
    tray = {}
    tray.x = back.x
    tray.y = back.y
    tray.width = back.width
    tray.height = back.height
    
    – Some trays are left or top justified – need to adjust…
    – NOTE: x, yreference not supported in corona graphics 2.0 – new code added
    print(" tray x,y == “, tray.x, tray.y)
    print(” back.anchorX == “, back.anchorX)
–[[    
    if( back.anchorX ~= 0.5 ) then
        tray.x = tray.x - (tray.width * back.anchorX)
        print(” – moving tray.x -->", tray.x)
    end
–]]    
    
    print(" back.anchorY == “, back.anchorY)
    if( back.anchorY ~= 0.5 ) then
        print(” – adjusting tray.y")
        tray.y = tray.y - (tray.height * back.anchorY)
    end    
    
    print(" final tray x,y == ", tray.x, tray.y)

–[[            
    if( back.xReference ~= 0 ) then
        tray.x = tray.x - back.xReference
    end
    
    if( back.yReference ~= 0 ) then
        tray.y = tray.y - back.yReference
    end    
–]]    
–    print(" xy reference == “, back.xReference, back.yReference)
    
    if( yOffset == nil ) then
        yOffset = 0
    end
    
    editX = tray.x       – Coords for the field…
    editY = tray.y + yOffset
        
    tray.y = tray.y + yOffset
    
–    print(”  editX, editY == ", editX, editY)
    callingText = userText     – Use the passed in text field for init and results…
    
    – Set up the editing vars, if not passed in…
    if( keyboardType == nil )
        then keyboardType = “default”
    end
    
    if( isSecure == nil ) then
        isSecure = false
    end

    this = createEditTextField(keyboardType, isSecure)     
    userCallBack = callBack

    return this
end

– function to remove listeners, etc, added by new()
function release(  )

    print (" release" )

    if( not isSimulator ) then – Corona simulator does NOT support input text fields… booooo
        removeEditTextField()        – Make sure this field is gone
    end
    
    if( this ~= nil ) then
        this:removeSelf()
        this = nil
    end

–    this.ButtonLogin:removeEventListener()

end

[/lua]

A listener for a fields background rectangle looks like

[lua]

local function nicknameListener(event)  – Called when user clicks in nickname text edit rectangle… Allows user to edit the text…
    print(" – nicknameListener(event) called.")
–    audio.play( mojoData._TapAudio, { channel=mojoData._sfxChannel, loops=0, fadein=0 }  )  – button pressed sfx
    
    group.NickNameText.isVisible = false    – Hide the onscreen text while editor is up…
    group.nicknameEditField = editField.new(group.NickNameText.text, group.NicknameBack, nicknameEditDone, “default”, false, 0, 20)      – Field the user is editing… (native text field)
    group:insert(this.nicknameEditField)      – Add it to the display…

[/lua]

And the callback (called back when editing is done) looks like

[lua]

local function nicknameEditDone(event)    – Callback function from the nickname editField function… Called when editing is completed.

    print(" --nicknameEditDone() called back from editField")
–    audio.play( mojoData._EditDone, { channel=mojoData._sfxChannel, loops=0, fadein=0 }  )      
    
    if( group ~= nil ) then       
        local nicknameText = editField.getText()
        if( utils.isEmpty(nicknameText) == false ) then
            group.NickNameText.text = nicknameText
        end
       
        group.NickNameText.isVisible = true                 – Make the onscreen text visible again
        group.NickNameText:toFront()
        
        if( group.nicknameEditField ~= nil ) then
            print(" – deleting old messagefield")
            group:remove(this.nicknameEditField)
            group.nicknameEditField = nil
        end
        
        print(" – text set to: ", group.NickNameText.text)
    end

end

[/lua]

Also, note that if the user is in the middle of editing a field, and taps outside the field on another object on the screen, you can instantly end editing by calling     native.setKeyboardFocus( nil ), which will invoke the editField “end” phase (which in turn will invoke your callback). (You don’t have to reset focus, you could allow the user adjust an onscreen slider while in the middle of editing if you wanted).


Caveat emptor: I haven’t really cleaned up the comments / debug stuff I put in there when porting to G2.0, so, there’s a bunch of stuff that could just be deleted (which is commented out right now) to clean it up a lot (a little refactoring wouldn’t hurt either…) Best wishes.

You would have to make it by your own… or just use the atanas widget (http://forums.coronalabs.com/topic/42977-widgetneweditfield-beta-testers-needed/page-4#entry228827

+1 for newEditField… All you have to do is throw a maxChars = 10, etc in the constructor.

thanks all for your responses, 

I am trying to add newEditField but still not successful… i have posted a question in the widgetstown forum about the issue I am facing. generally i see it as very promising  :slight_smile:

Thanks

Abdul

I’ve got some keyboard entry stuff you can look at. It has a couple references to some utility functions I use (like utils.isAndroid, or utils.isSimulator) that you can pretty easily find in the forums if you want to adapt the idea.

Although it’s intended as a reference – it works (with G2.0), and the strategy is to A) never have native fields on the screen (except while actually editing), and B) use a centralized editing routine that will callback specific app code when the user is done (so the user can use a non-native text object when editing is done).

With this strategy, (rounded) rectangles are used to lay out where your entry fields will be (and take the initial tap event), and display.newText objects represent your fields when not in the process of editing (on top of the rounded rectangles). So – when not editing, everything is a standard display object / plays nicely with transitions, tableViews, etc… (a source of many headaches, if you have native fields onscreen all the time).

Once the user taps a rectangle input field area (remember, you put listeners on the rectangles), your listener calls to create an editField object (basically, a temporary native field). When the user is done editing (hits enter), the editField code calls a function (you specified) back. At that point the native field is removed, the standard display.newText object is updated, and your app code can do bounds checking on numeric input, update counters, etc, as needed (and everything is back to standard objects)…

This also avoids most of the problems devs run into when trying to do offscreen text input, since the actual native input is done onscreen, totally legit from an OS standpoint (devs usually do offscreen input to avoid the problem of always having native fields onscreen / on top of other objects).

It does some other little things, like limiting input length, making a buzz noise, etc, but you’ll want to think through the overall input needs of your app, consider Coronas capabilities / limitations, and devise a strategy (such as outlined above) that will let your app jump through all the hoops it needs to regarding display, movement, editing, etc of text input fields…

Anyways… although the strategy might be somewhat sophisticated, the code maybe not so much… Hopefully there’s something here that will help you get some ideas on ways to (or not to) jump through some of the hoops

[lua]

module(…, package.seeall)

– editField.lua
– Corona SDK basic keyboard entry api…
– mpappas, 2012 – copy, share, enjoy. Throw me a credit now and then :wink:

– Ported to g2.0 2013 (needs a bit of cleanup of commented code)

– call editField.new() to create / start the keyboard entry. The overall idea is that the calling code passes in a rectangle object
– (typically the frame area for the input area), and a few parameters (type of kb, max length of entry, a callback function when done, etc).
– This code will then create a native editfield, exactly the size of the rectabgle and do text input within those bounds (at a max length as passed in, etc).
– When the user dismisses the kb, the native field is removed, and the users callback is executed so that the entry can be displayed as a non-native field,
– on top of the original rectangle (passed in).

– The code also includes a font size calculator, called once automatically to set the native font size (tricky on droid).

–   Usage example:
–           group.nicknameEditField = editField.new(group.NickNameText.text, group.NicknameBack, nicknameEditDone, “default”, false, 0, 20)

–          Where: “group” is a display group…
–                 NickNameText is a text display object, in front of…
–                 NickNameBack which is typically a white rectangle frame for the text area…
–                 nicknameEditDone is a callback function to be executed when the user dismisses the kb…

–          Note that if the user taps outside the edit field, normal user code touch handlers will still fire off. To stop any possible
–          editing that could be occuring on a screen/remove native kb, call editField.removeEditTextField() (which will remove kb/do callbacks etc if necc.)
–          Setting kb focus to nil will also trigger the end phase of text editing automatically.

local this = nil
local utils = require(“utils”)
mojoData = require(“mojodata”)

editText = “”
local tray = nil            – passed in object that sits behind the text field
callingText = nil           – calling fuinctions text field to change/alter

local editTextField = nil       – Onscreen nativeTextField(s) that corona uses for input… NOT available in simulator… booo…
local userCallBack = nil             – function to call back the user when edit is completed…

– Below is the function prototype for the keyboard handler…
local keyboardHandlerEditText


local isAndroid = “Android” == system.getInfo(“platformName”)
local isSimulator = “simulator” == system.getInfo(“environment”)
local inputFontSize = nil           – Will be calculated at runtime…
local targetFontSize = 18       – point size we shoot for, relative to an iphone 5 (scaled up for larger screens, down for smaller, relatively)
local maxEditLength = 50        – Maximum length a string can be, set in new to 2000 or some giant number, for messages…

local function calcFontSize()
    print(" – calcFontSize()")
    print("-----------------------" )    
            
    local sysType = system.getInfo(“architectureInfo”)
    print(" – sysType == “, sysType)            
    print(” – display.contentScaleY  == “, display.contentScaleY )
    print(” – display.screenOriginY  == “, display.screenOriginY )          
    
    inputFontSize = targetFontSize / display.contentScaleY    – old method is fallback (ends up being sim setting)
    local heightIn = 4
    local fontScale = 1
    
    if( utils.isAndroid == true ) then      – try and get the real width / height and deal with it            
        print(” – -- Android font size calc…")
        
        local missingInches = display.screenOriginY * -2     – account for both top and bottom area (x2), and change the sign sign since originY is always negative, if it exists…
        
        missingInches = missingInches / 320             – 320 is 1 inch, in my 640x960 virual content space (960 == 3 inches for my app, designed for a standard iphone 4 display)        
                                                        – different contentScale sizes will use a different virtual pixel / inch value (eg, 320x480 virtual content = missingInches / 160)
–        missingInches = 0       – testing… if corona compensates… then this is not needed…
        
        print(" – missing inches == “, missingInches)
        
        heightIn = system.getInfo( “androidDisplayHeightInInches” )
        local widthIn = system.getInfo( “androidDisplayWidthInInches” )
        print(” – original height == “, heightIn)
        
        heightIn = heightIn - missingInches               
     
        --Make sure its not nil… e.g. the simulator will return nil, perhaps some bad devices will too…
        if heightIn ~= nil then
            – heightIn is height of actual droid app is running on
            fontScale =  heightIn / 3.0 – 3.0 is actual iPhone 3gs /4 /4s height
            print(” – fontsize set on actual droid screen inch height")
–            print(" – widthIn = “, widthIn)
–            print(” – heightIn = “, heightIn)
        else
            fontScale = 4/3  --Default to a 4 inch diagonal (iphone is 3.0)
            print(” – fontsize set to 4 inch phone size")
        end
        
        print(" heightIn == “, heightIn)
        print(” fontScale == “, fontScale)
        inputFontSize = targetFontSize*fontScale            
    else                                    – else is iOS
        print(” – -- iOS font size calc…")
        heightIn = 3                                  – default to stnadard iPhone size        

        local missingInches = display.screenOriginY * -2    – account for both top and bottom area (x2), and change the sign sign originY is negative, if it exists…
        
        missingInches = missingInches / 320             – 320 is 1 inch, in my 640x960 virual content space (960 == 3 inches for my app, designed for a standard iphone 4 display)
                                                        – different contentScale sizes will use a different virtual pixel / inch value (eg, 320x480 virtual content = missingInches / 160)        
–        missingInches = 0       – testing… if corona compensates… then this is not needed…
        print(" – missing inches == ", missingInches)

        –
        – Since there is no corona facility to get the screen height of the device on iOS, we’ll determine it ourselves.
        –
        if( sysType == “iPhone2,1” ) then       – 3GS        
            heightIn = 3.0 - missingInches      – original iPhone size
            print(" – iPhone 3GS detected")        
        elseif( string.match(sysType, “iPhone3”) or string.match(sysType, “iPhone4”) ) then       – iPhone 4, 4S        
            heightIn = 3.0 - missingInches      – Same size as the old 3gs- better resolution, but same size
            print(" – iPhone 4 detected")        
        elseif( string.match(sysType, “iPhone5”)  ) then       – iPhone 5
            heightIn = 4.0 - missingInches      – Should go back to 3, after missing inches chopped off by corona are deducted.
            print(" – iPhone 5 detected")      – This phones screen is taller, a little… Corona will end up chopping it off though
        elseif( string.match(sysType, “iPod5”) ) then       – new, tall iPad
            heightIn = 4.0 - missingInches      – Should go back to 3, after missing inches chopped off by corona are deducted.            
        elseif sysType == “iPad2,5” or sysType == “iPad2,6” or sysType == “iPad2,7” or sysType == “iPad2,8” then    – 2,8 is unknown, just a guess at next mini #
            heightIn = 6.25 - missingInches     – mini
            print(" – iPad mini detected")     – A good amount taller. Need a much bigger point size for this device, for the input fonts to look scaled right     
        elseif( string.match(sysType, “iPad”) ) then       – standard iPad
            heightIn = 7.75 - missingInches     – iPad
            print(" – iPad detected")          – MUCH taller screen, really gonna need to scale fonts up in point size for this bad boy (or they will look less than half size for the field)            
        else
            print(" – unrecognized iOS device, using default 3.5 inches tall") – iPods will fall to here, they are 3.5 anyways…
            if( missingInches == 0 ) then
                – iPod falls through to here (and it is 3 inches tall, and any missing inches accounted for in a tall version, so that works for now)
                heightIn = 3.0 - missingInches  – I would hope this is typical, zero extra on an unknown ios device
            else
                heightIn = 4.0 - missingInches  – otherwise, we’ll take a flying guess that the unknown device is bigger than a tiny breadbox, and smaller than a car. (4 inches tall, iphone 5 format)
            end
        end        

        fontScale =  heightIn / 3.0                 – 3.0 inches is actual iPhone 4 height (that my content is based on)
        print(" heightIn == “, heightIn)
        print(” fontScale == “, fontScale)
        inputFontSize = targetFontSize*fontScale            
    end
                
    print(” – final fontsize == “, inputFontSize)
    print(”-----------------------" )    
    return inputFontSize
end

function getText()      – returns last value test set to
    return editText
end

function setText(text)      – sets value…
    editText = text
end

local function createEditTextField(keyboardType, isSecure)

    print( " – Creating EditTextField, tray ==", tray)

    if( editTextField == nil) then
                
        if( inputFontSize == nil ) then     – First timer?
            calcFontSize()                  – Determine the device native scale / font size to use
        end
        
        local tempSize = inputFontSize
        if( tray.height < 66) then                – small  tray means we use a smaller font…
            tempSize = inputFontSize * 0.9
        end        

–        local tempX = (tray.x - tray.width/2) + 10  – Crimp it in side to side
        local tempX = tray.x  – + 10  – Crimp it in side to side
        local tempW = tray.width - 10
        local tempY, tempH
        
        
        tempY = tray.y  – ios
        tempH = tray.height
        
        – following was needed in corona g1.0, seems to be fixed in g2.0
        --[[        
        if( utils.isAndroid == true ) then  – Special issue with android – font size is larger than bounding box in some cases…
                                            – Causes the text to position weird…
            tempH = tray.height * 2         – inputFontSize?? What should it equal!!!
            tempY = (tray.y - tempH/2)      – a little extra for android
            print(" – android, adjusted tray y,h")
        else
–            tempY = (tray.y - tray.height/2)  – ios
            tempY = tray.y  – ios
            tempH = tray.height
            print(" – iOS, using tray.h,w")
        end
        --]]
        
–        print(" tempH == “, tempH)
        
        if ( tempH < 42 ) then   
            tempH = 42
        end                
        
        tempX = tempX + tempW/2 – Added for graphics 2.0, all native fields init’d with center coords
        
        editTextField = native.newTextField( tempX, tempY, tempW, tempH, keyboardHandlerEditText)
        editTextField.font = native.newFont( native.systemFont, tempSize )
–        editTextField.size = tempSize
        editTextField.inputType = keyboardType
        editTextField.align = ‘left’;
        editTextField.text = editText
        editTextField.isEditable = true
        editTextField:setTextColor( 0,0,0 )        – Native field apparently still uses setTextColor, not setFillColor after g2.0 release…
–        editTextField:setFillColor( 0,0,0 )        
        editTextField.hasBackground = false     – true     – use true for debugging position of field
        editTextField.isSecure = isSecure
        print(”  editTextField created – textSize ==", tempSize)
        print(" x,y == “, editTextField.x, editTextField.y)
    else
       print(”   – editTextField ~= nil")
    end

–    print("  – Giving editTextField focus")
    native.setKeyboardFocus( editTextField )  – Get the keyboard coming onscreen…
    
    return editTextField
end

function removeEditTextField()

–    print( "  *** Deleting editTextField", userCallBack)

–        native.setKeyboardFocus( nil )                      – Tell the os to get rid of the keyboard/end the editing)

    if( editTextField ~= nil ) then
–        print(“a”)
        editText = editTextField.text                       – Set the var passed to the login server call…
–        print(“b”)        
        callingText = editText                     – sets the calling routines field…
–        editTextField:removeSelf()
        
–        print(" **** CALLERS TEXT SET TO: ", callingText)

–        editTextField:removeSelf()              – These must be manually removed, or they stay onscreen even after a screen change…
–        print(“c”)
–        print("    – editTextField removed. Calling back…")
        if( userCallBack ~= nil ) then
–            print(“d”)
            
            – Setting up a tempcallback var, in case callback creates a new field, so we dont nil it…
            local tempCallBack = utils.deepCopy(userCallBack)
            userCallBack = nil            
            tempCallBack()

–            print(“Callback completed”)
        else
            print(" – calbback == nil")
        end       
        editTextField = nil     – Finally, set it to nil        
        native.setKeyboardFocus( nil )    
        
     else
–        print("    – editTextField already was deleted.")
     end
     
–    print( "  *** removeEditTextField() done.")     

end

function keyboardHandlerEditText(event) – handles the pop up keyboard when editing

–    print("******")
–    print( " Keyboard handler editText entered – phase: “, event.phase )
–    print(” – target == ", event.target)

–    if( editTextField == nil and (event.phase ~= “ended”) ) then
–        print("  *** editTextField == nil!! drats!")
–        return true
–    end

    if (event == nil) then                                         – Don’t know why I’m seeing no event/phase sometimes (after ENDED phase)
        print(" — event == nil, exiting — event == ", event )
        return true
    end

    if (event.phase == nil) then
        print(" — event.phase == nil, exiting — event.phase == ", event.phase )
        return true
    end

    if ( event.phase == “began” ) then
–        print( "  editText event began")
–        native.setKeyboardFocus( editTextField )  – They finished editing, dismiss the keyboard
    end
    
    if( event.phase == “editing” ) then
–        print("  -event.newCharacters == “, event.newCharacters)
        if( editTextField ~= nil ) then
            if( event.newCharacters  == “\n” ) then
    –            print(” --newline detected")
                editText = editTextField.text                       – Set the var passed to the login server call…
                editTextField.isEditable = false
    –            native.setKeyboardFocus( nil )            
    –            print(" – focus set to nil")
                removeEditTextField()
            else
                if( string.len(editTextField.text) > maxEditLength ) then
                    – We need to delete the char, wherever in the string they are editing…
                    local tempText
                    
                    if( event.startPosition == 1 ) then
                        tempText = editTextField.text:sub(2, -1 )                                   – Take them all except that first one they just entered
                    elseif( event.startPosition == string.len(editTextField.text) ) then            – Take em all except the last one…               
                        tempText = editTextField.text:sub(1, string.len(editTextField.text) - 1 )   – Take them all except that first one they just entered                
                    else
                        tempText = editTextField.text:sub(1, event.startPosition-1 )                – First part…
                        tempText = tempText … editTextField.text:sub(event.startPosition+1, -1 )   – Last part…                    
                    end
                
                    editTextField.text = tempText      – editTextField.text:sub(1, string.len(editTextField.text)-1)        – remove the new char
                    audio.play( mojoData._NotifyAudio2, { channel=mojoData._sfxChannel, loops=0, fadein=0 }  )  – negative sfx
                end
            
            end
    –        utils.printTable( event, " Event", 3 )
        end
    end    
    if ( event.phase == “submitted” ) then
–        print( " Keyboard handler editText submitted detected --")
        if( editTextField ~= nil ) then     – just to be safe…        
            native.setKeyboardFocus( nil )     – ** – Tell the os to get rid of the keyboard/end the editing)
–            removeEditTextField()
            
–            print(" – Have a edit field")
        else
            print( "    editTextField == nil")
        end
    end

    if ( event.phase == “ended” ) then
        removeEditTextField()

–        print( " Keyboard handler editText ended detected --")
        if( event.target ~= nil ) then
            if( editTextField ~= nil ) then     – just to be safe…        
                – hmmm…
–                editText = editTextField.text                       – Set the var passed to the login server call…
–                removeEditTextField()       – **
            end
        else
            print( " event.target == nil" )
        end
    end

–    print("******")
   return true      – flag that we dealt with the event
end

function new (userText,back, callBack, keyboardType, isSecure, yOffset, maxLen)     – Called with the object that text sits on top of… yOffset is used if/when screen scrolls to accomodate keyboard

    print(" – new editField called… usertext == “, userText)
    print(” – yOffset == “, yOffset)
    
    if( utils.isSimulator == true ) then
        yOffset = 0  – graphics 2.0 updates the sim coords differently it seems…
    end
    
    if( maxLen == nil ) then
        maxEditLength = 2000        – A descip or a mesage can be up to this length…
    else
        maxEditLength = maxLen
    end
–    print(”  – back == ", back)

    – First make sure they weren’t already editing a different edit field…
    native.setKeyboardFocus( nil )       – Tell the os to get rid of the keyboard/end the editing)
        
–    if( tray ~= nil ) then
    if( editTextField ~= nil ) then
–        print(" – manually removing edit field in new()")
        removeEditTextField()   – Get rid of the old one…
    end
    
    editText = userText     – Use the passed in text as the basis…
    
–    print("*** Entered editField:new()")

    – set the edit fields coords to the passed in objects coords
    --tray = utils.deepCopy(back)     – Set to the passed in back object / tray the text sits on *** ONLY DEEPCOPIES A POINTER == arghhh
    
    tray = {}
    tray.x = back.x
    tray.y = back.y
    tray.width = back.width
    tray.height = back.height
    
    – Some trays are left or top justified – need to adjust…
    – NOTE: x, yreference not supported in corona graphics 2.0 – new code added
    print(" tray x,y == “, tray.x, tray.y)
    print(” back.anchorX == “, back.anchorX)
–[[    
    if( back.anchorX ~= 0.5 ) then
        tray.x = tray.x - (tray.width * back.anchorX)
        print(” – moving tray.x -->", tray.x)
    end
–]]    
    
    print(" back.anchorY == “, back.anchorY)
    if( back.anchorY ~= 0.5 ) then
        print(” – adjusting tray.y")
        tray.y = tray.y - (tray.height * back.anchorY)
    end    
    
    print(" final tray x,y == ", tray.x, tray.y)

–[[            
    if( back.xReference ~= 0 ) then
        tray.x = tray.x - back.xReference
    end
    
    if( back.yReference ~= 0 ) then
        tray.y = tray.y - back.yReference
    end    
–]]    
–    print(" xy reference == “, back.xReference, back.yReference)
    
    if( yOffset == nil ) then
        yOffset = 0
    end
    
    editX = tray.x       – Coords for the field…
    editY = tray.y + yOffset
        
    tray.y = tray.y + yOffset
    
–    print(”  editX, editY == ", editX, editY)
    callingText = userText     – Use the passed in text field for init and results…
    
    – Set up the editing vars, if not passed in…
    if( keyboardType == nil )
        then keyboardType = “default”
    end
    
    if( isSecure == nil ) then
        isSecure = false
    end

    this = createEditTextField(keyboardType, isSecure)     
    userCallBack = callBack

    return this
end

– function to remove listeners, etc, added by new()
function release(  )

    print (" release" )

    if( not isSimulator ) then – Corona simulator does NOT support input text fields… booooo
        removeEditTextField()        – Make sure this field is gone
    end
    
    if( this ~= nil ) then
        this:removeSelf()
        this = nil
    end

–    this.ButtonLogin:removeEventListener()

end

[/lua]

A listener for a fields background rectangle looks like

[lua]

local function nicknameListener(event)  – Called when user clicks in nickname text edit rectangle… Allows user to edit the text…
    print(" – nicknameListener(event) called.")
–    audio.play( mojoData._TapAudio, { channel=mojoData._sfxChannel, loops=0, fadein=0 }  )  – button pressed sfx
    
    group.NickNameText.isVisible = false    – Hide the onscreen text while editor is up…
    group.nicknameEditField = editField.new(group.NickNameText.text, group.NicknameBack, nicknameEditDone, “default”, false, 0, 20)      – Field the user is editing… (native text field)
    group:insert(this.nicknameEditField)      – Add it to the display…

[/lua]

And the callback (called back when editing is done) looks like

[lua]

local function nicknameEditDone(event)    – Callback function from the nickname editField function… Called when editing is completed.

    print(" --nicknameEditDone() called back from editField")
–    audio.play( mojoData._EditDone, { channel=mojoData._sfxChannel, loops=0, fadein=0 }  )      
    
    if( group ~= nil ) then       
        local nicknameText = editField.getText()
        if( utils.isEmpty(nicknameText) == false ) then
            group.NickNameText.text = nicknameText
        end
       
        group.NickNameText.isVisible = true                 – Make the onscreen text visible again
        group.NickNameText:toFront()
        
        if( group.nicknameEditField ~= nil ) then
            print(" – deleting old messagefield")
            group:remove(this.nicknameEditField)
            group.nicknameEditField = nil
        end
        
        print(" – text set to: ", group.NickNameText.text)
    end

end

[/lua]

Also, note that if the user is in the middle of editing a field, and taps outside the field on another object on the screen, you can instantly end editing by calling     native.setKeyboardFocus( nil ), which will invoke the editField “end” phase (which in turn will invoke your callback). (You don’t have to reset focus, you could allow the user adjust an onscreen slider while in the middle of editing if you wanted).


Caveat emptor: I haven’t really cleaned up the comments / debug stuff I put in there when porting to G2.0, so, there’s a bunch of stuff that could just be deleted (which is commented out right now) to clean it up a lot (a little refactoring wouldn’t hurt either…) Best wishes.