Different keyboard flavours in iOS


I was wondering what would be the best way in JUCE to assign a specific type to the iOS keyboard.

For instance, when a TextEditor pertaining a numeric value gains the focus, the keyboard should be setup for numeric input.

I believe I should set the 'keyboardType' property of the UITextField, but where? Could I do this through Component::getPeer()?

Is this something that you plan to add, Jules?


It'd probably be best added as a new virtual method on the TextInputTarget class, but I've no time to look at it right now..

Hello Jules,

Here is my solution, if you believe it is acceptable, as I hope, could you add it to Juce? I have tested it in iOS, but I've never touched Android, so I can only hope it is suitable for that OS.

1. Declare a VirtualKeyboardType enum inside TextInputTarget to provide a list of types as a reasonable intersection between those defined in iOS and those defined in Android.

2. Declare a VirtualKeyboardType member variable and set/get methods inside TextInputTarget.

class JUCE_API  TextInputTarget

enum VirtualKeyboardType
    // iOS: UIKeyboardTypeDefault, Android: text

    // iOS: UIKeyboardTypeNumbersAndPunctuation, Android: number|numberSigned|numberDecimal

    // iOS: UIKeyboardTypeURL, Android: textUri

    // iOS: UIKeyboardTypePhonePad, Android: phone

    // iOS: UIKeyboardTypeEmailAddress, Android: textEmailAddress

    /** */
        : virtualKeyboardType(virtKbdTypeDefault) 

    /** Destructor. */
    virtual ~TextInputTarget() {}

    /** Returns true if this input target is currently accepting input.
        For example, a text editor might return false if it's in read-only mode.
    virtual bool isTextInputActive() const = 0;

    /** Returns the extents of the selected text region, or an empty range if
        nothing is selected,
    virtual Range<int> getHighlightedRegion() const = 0;

    /** Sets the currently-selected text region. */
    virtual void setHighlightedRegion (const Range<int>& newRange) = 0;

    /** Sets a number of temporarily underlined sections.
        This is needed by MS Windows input method UI.
    virtual void setTemporaryUnderlining (const Array <Range<int> >& underlinedRegions) = 0;

    /** Returns a specified sub-section of the text. */
    virtual String getTextInRange (const Range<int>& range) const = 0;

    /** Inserts some text, overwriting the selected text region, if there is one. */
    virtual void insertTextAtCaret (const String& textToInsert) = 0;

    /** Returns the position of the caret, relative to the component's origin. */
    virtual Rectangle<int> getCaretRectangle() = 0;

    /** Sets the current virtual keyboard type. */
    virtual void setVirtualKeyboardType (VirtualKeyboardType type) { virtualKeyboardType = type; }

    /** Gets the current virtual keyboard type. */
    virtual VirtualKeyboardType getVirtualKeyboardType () { return virtualKeyboardType; }

    VirtualKeyboardType    virtualKeyboardType;

3. Modify methods derived from ComponentPeer::textInputRequired() as needed, so that they can set the desired type of keyboard in the specific OS.

void UIViewComponentPeer::textInputRequired (const Point<int>&)
if (TextInputTarget* const target = findCurrentTextInputTarget())
        case TextInputTarget::virtKbdTypeDefault:
            view->hiddenTextView.keyboardType = UIKeyboardTypeDefault;

        case TextInputTarget::virtKbdTypeNumbers:
            view->hiddenTextView.keyboardType = UIKeyboardTypeNumbersAndPunctuation;

        case TextInputTarget::virtKbdTypeURL:
            view->hiddenTextView.keyboardType = UIKeyboardTypeURL;

        case TextInputTarget::virtKbdTypePhonePad:
            view->hiddenTextView.keyboardType = UIKeyboardTypePhonePad;

        case TextInputTarget::virtKbdTypeEmailAddress:
            view->hiddenTextView.keyboardType = UIKeyboardTypeEmailAddress;

OK, that's all, thank you for your attention!

1 Like

Thanks! I'll have a go at rolling something like this in there asap!

Thank you, Jules!

By any chance - is there something like this for Android? There’s an android:inputType setting that does the same job.