A.Sharma
A.Sharma

Reputation: 2799

JavaFX TextField Focused Property Issue in Gluon Mobile

I have a couple of things going on in my view when porting the app to mobile (on iOS).

  1. When I start a scroll with touching a TextField, the textfield focuses then stays fixed on the screen during scroll.
  2. I put some validation on the field such that when the field is put out of focus, a modal pops up specifying the error. However, in iPhone, the textfield stays focused and appears over the dialog.

Note that I am using a JavaFX native touch field and not the Gluon version because I had issues with the focusedProperty for the Gluon version of the TextField. The way it works is that if the input is invalid, it will set the value of the field to an empty string and open the dialog.

I have tried the following approaches:

  1. Prior to showing the modal, requestFocus on the View.
  2. While scrollpane is scrolling, requestFocus on the scroll pane (the scrollpane has its own custom skin which I can add the requestFocus on it while it is scrolling).

enter image description here

enter image description here

Upvotes: 1

Views: 399

Answers (1)

José Pereda
José Pereda

Reputation: 45476

The problem you are facing will happen with either the JavaFX TextField and the Gluon`s one, as the latter internally uses the built in JavaFX control.

The reason of the issue on iOS is this: When the JavaFX TextField gets the focus, a native iOS UITextField is added on top of the control, basically to enable the interaction with the native software keyboard.

You can see that the TextFieldBehavior has a specific call on iOS:

private void handleFocusChange() {
    TextField textField = getControl();

    if (textField.isFocused()) {
        if (PlatformUtil.isIOS()) {
            ...
             textField.getScene().getWindow().impl_getPeer().requestInput(text, type.ordinal(), w, h, 
                    trans.getMxx(), trans.getMxy(), trans.getMxz(), trans.getMxt(),// + insets.getLeft(),
                    trans.getMyx(), trans.getMyy(), trans.getMyz(), trans.getMyt(),// + insets.getTop(),
                    trans.getMzx(), trans.getMzy(), trans.getMzz(), trans.getMzt(), textField.getFont().getSize());
            ...
        }
    }
}

that goes directly to the native implementation:

UITextField* textField = [[UITextField alloc] initWithFrame:CGRectMake(mxt + 1, myt + 1, mxx * (width - 2), myy * (height - 2))];

So far this works fine as long as you don't scroll and move the JavaFX TextField initial position while the native UITextField is visible.

Also note that the iOS layer with the native control is on top of the JavaFX layer (that's why you keep seeing the native editor on top of the dialog).

There is an open PR to support updating the native control position when the software keyboard shows up, translating both the JavaFX and the iOS control, and introduces the updateBounds method, that could be used in case a scroll event moves the TextField.

In the meantime, you will have to add some workaround to prevent scrolling while the TextField is focused.

Upvotes: 3

Related Questions