[SOLVED] support iOS on screen keyboard with robovm

Any community contributions to libgdx go here! Some may get included in the core API when permission is granted.

[SOLVED] support iOS on screen keyboard with robovm

Postby ariellaub » Mon Dec 02, 2013 8:59 am

Hi, we're new to libgdx and we know supporting iOS on screen keyboard is on your table but it's really urgent for us so we decided to try and implement it ourselves.. so far it's not going well so I'm just looking for some directions, I'll explain what we did and the outcome:

Attempt #1:
1. I've followed the instructions given in this thread: http://stackoverflow.com/questions/7253 ... ngl-es-app.
2. I've implemented the UIKeyInput of the IOSUIView class (also used it for the view member as it was unused before and the view was a GLKView directly). I've also added the canBecomeFirstResponder as described in the thread.
3. In IOSInput I've implemented setOnScreenKeyboard to set graphics.view to be the first responder or resign depending on the visible variable.

Outcome:
When I create a text input field and press it the input.setOnscreenKeyboard function is called and I even see that the canBecomeFirstResponder of my view is called so it seems like the os is actually initiating something but the keyboard never comes on screen..


Attemp #2:
1. I've examined how MOAI implement the iOS keyboard. It's dirty… they create a real UITextField and set it to hidden. Then they set it to become the first responder and redirect its input to their framework.
2. I've created a similar hidden UITextField view and added it as a subview to the application window view. I then passed it to IOSInput so it will be set or resigned first responder when the keyboard should be shown.

Outcome:
Keyboard again is not showing and also the libgdx input field looses focus for some reason…


We'll continue our effords but just wanted to outline what we're doing maybe someone can tell us we're wasting our time and should work around this… The reason this is so important is that an app we are writing includes a chat module which should support unicode, and we can't implement our own keyboard for all available languages..
Last edited by ariellaub on Tue Dec 03, 2013 8:25 pm, edited 1 time in total.
ariellaub
 
Posts: 11
Joined: Mon Dec 02, 2013 8:46 am

Re: [SOLVED] trying to hook the iOS keyboard

Postby ariellaub » Tue Dec 03, 2013 8:08 pm

Good news! I've been able to add a native keyboard for iOS and it seems to work great with the libGDX textfield as well.

So the path I tookk is the "dirty" one. As I mentioned MOAI is using a similar approach but mine is a bit cleaner and really just uses the hidden UITextField as a target for the keyboard but all the user input is "rejected" by the delegate I provide and are tunnelled to through the libGDX inputProcessor.

The code I changed is all in the IOSInput class:

1. Added a private class for my hidden UITextField, extending the UITextField is really just needed to take control over the keyboard backspace via the deleteBackward override:
Code: Select all
   private class HiddenTextField extends UITextField {
      public HiddenTextField(CGRect frame) {
         super(frame);
         
         setKeyboardType(UIKeyboardType.Default);
         setReturnKeyType(UIReturnKeyType.Done);
         setAutocapitalizationType(UITextAutocapitalizationType.None);
         setAutocorrectionType(UITextAutocorrectionType.No);
         setSpellCheckingType(UITextSpellCheckingType.No);
         setHidden(true);
      }
      
      @Override
      public void deleteBackward() {
         app.input.inputProcessor.keyTyped((char)8);
         super.deleteBackward();
      }
   }
   private UITextField textfield = null;


2. Implement a UITextDelegate that will tunnel all the input to libGDX, it also controls the 'return' button on the keyboard, in this case always allowing to return and close the keyboard:
Code: Select all
   private UITextFieldDelegate textDelegate = new UITextFieldDelegate.Adapter() {         
      @Override
      public boolean shouldChangeCharacters(UITextField textField, NSRange range, String string) {
         char[] chars = new char[string.length()];
         string.getChars(0, string.length(), chars, 0);
         for(int i=0; i<chars.length; i++) {
            app.input.inputProcessor.keyTyped(chars[i]);
         }
         return false;
      }
      
      @Override
      public boolean shouldReturn(UITextField textField) {
         app.log("debug","shouldReturn called");
         textField.resignFirstResponder();
         return false;
      }         
    };


3. Implement the setOnscreenKeyboard empty methof of IOSInput so that it brings the hidden text field into/out of focus:
Code: Select all
   @Override
   public void setOnscreenKeyboardVisible(boolean visible) {
      app.log("debug", "showing keyboard "+String.valueOf(visible));
      if (textfield == null) {
         textfield = new HiddenTextField(new CGRect(10, 10, 100, 50));
         app.getUIViewController().getView().addSubview(textfield);
      }
      
      if (visible) {
         textfield.becomeFirstResponder();
         textfield.setDelegate(textDelegate);
      }
      else {
         textfield.resignFirstResponder();
      }
   }


Note that the UITextField is lazy loaded the first time the keyboard is shown so for apps not using the keyboard there is no overhead. For apps that do use the keyboard we prefered leaving one textfield live instead of generating a new one each time you want to show the keyboard..

Hope I didn't miss anything but with these changes the keyboard is now working for me in iOS! it's not tweaked yet and doesn't really allow you to control the different iOS keyboard attributes (I've hard coded what I needed in the HiddenTextField constructor,

I'll try to upload a screenshot.
Attachments
ioskeyboard.png
Screenshot of keyboard
ioskeyboard.png (110.94 KiB) Viewed 12801 times
ariellaub
 
Posts: 11
Joined: Mon Dec 02, 2013 8:46 am

Re: [SOLVED] trying to hook the iOS keyboard

Postby ariellaub » Tue Dec 03, 2013 8:23 pm

PS, I've forgot to thank Sergey, his post helped me solve this:
https://groups.google.com/forum/#!msg/r ... XhPPazPBUJ

also wanted to mention how cool robovm is and it's really powerful to have the exact same API as natives apps.. I still don't understand why my first approach (which seems like a better design) failed but this solution is good enough for us.

Still some todos which I'm not sure I'll get to:
1. Support moving the view up so the keyboard doesn't hide to bottom of the view. iOS gives you the coordinates to do this transition.
2. Expose the keyboard attributes so they can be modified from libGDX code (support decimal/email/password and other keyboards.
3. We didn't test this with unicode characters. Might work, might not...
ariellaub
 
Posts: 11
Joined: Mon Dec 02, 2013 8:46 am

Re: [SOLVED] support iOS on screen keyboard with robovm

Postby seibelj » Tue Dec 03, 2013 9:59 pm

Is there any plan to merge this into a release soon? This is critical for me as well. Thanks for your efforts.
seibelj
 
Posts: 3
Joined: Tue Dec 03, 2013 9:57 pm

Re: [SOLVED] support iOS on screen keyboard with robovm

Postby ariellaub » Tue Dec 03, 2013 10:15 pm

I'm not really sure how comfortable libGDX authors would be with this hidden field approach... I think the end result is perfect but if it's critical for you why don't you pull the sources and add it?

It's marely a change in the robovm backend so maintaining it should not be too hard, at least until it's officially supported in some way or another...
ariellaub
 
Posts: 11
Joined: Mon Dec 02, 2013 8:46 am

Re: [SOLVED] support iOS on screen keyboard with robovm

Postby seibelj » Tue Dec 03, 2013 10:23 pm

I will put it into my app, yes, but some type of longterm iOS keyboard solution needs to be prioritized.
seibelj
 
Posts: 3
Joined: Tue Dec 03, 2013 9:57 pm

Re: [SOLVED] support iOS on screen keyboard with robovm

Postby ariellaub » Tue Dec 03, 2013 10:33 pm

I know. but it is prioritized.

Mario put it in the robovm todo list but you cant expect any ETAs so if you want something working for now adopt this and I'm sure long term a solution will be provided as it's obvisouly possible..
ariellaub
 
Posts: 11
Joined: Mon Dec 02, 2013 8:46 am

Re: [SOLVED] support iOS on screen keyboard with robovm

Postby ThePhantasm » Tue Dec 10, 2013 6:10 am

Just to clarify - if I want to use your change, I'll need to build the libgdx source, right?
ThePhantasm
 
Posts: 15
Joined: Sun Nov 17, 2013 6:09 pm

Re: [SOLVED] support iOS on screen keyboard with robovm

Postby ariellaub » Tue Dec 10, 2013 8:34 pm

You'll need to rebuild the sources of the robovm backend only (export a JAR).

All changes are in one file "IOSInput.java".
ariellaub
 
Posts: 11
Joined: Mon Dec 02, 2013 8:46 am

Re: [SOLVED] support iOS on screen keyboard with robovm

Postby ariellaub » Thu Dec 12, 2013 8:10 pm

@ThePhantasm, per your request I've attached IOSInput.java.
It won't let me upload .java files so I renamed it to .txt, you can download it and rename back to .java.

I would gladly share the .jar of the backend itself but it wont let me either.

In order to build the robovm backend just replace the IOSInput file, then right click the robovm backend project and choose export. Then choose java and jar (not executable jar). It will guide you through some steps, the only important one is setting the output directory to which it will export the jar. the rest you can just go next, next... until you can hit finish.

(PS, assuming you are using Eclipse..)

Good luck!
Attachments
IOSInput.txt
(14.25 KiB) Downloaded 501 times
ariellaub
 
Posts: 11
Joined: Mon Dec 02, 2013 8:46 am

Next

Return to Libgdx Contributions

Who is online

Users browsing this forum: No registered users and 1 guest