3

In my Xamarin.iOS app (C#), I have a iPhoneOSGameView (which inherits from UIView), and I would like to capture key presses from an external (say bluetooth) keyboard.

Since this is to add support for keyboard control in a game, I want to be able to respond to these events without having to place a textbox or any other text field as proposed in this question (actually, they're not capturing key presses, but textbox changes, which is completely different from what I want to do)

In Android, I can achieve this by overriding OnKeyDown and OnKeyUp in my activity, but there seem to be no similar events either on UIView or UIViewController.

Is there a way to capture key presses and key releases in either UIView or UIViewController?

Since this is for Xamarin.iOS, I would certainly prefer a C# answer, but I guess I can read Objective-C if needed.

Community
  • 1
  • 1
Panda Pajama
  • 1,283
  • 2
  • 13
  • 31
  • @TaW: Why did you remove the c# tag? this is for a C# program, and I am expecting a C# answer. If a language tag is to be removed, it would be the objective-c tag. I left objective-c because objective-c answers are somewhat accepted as well, but C# is greatly preferred, since I cannot completely understand objective-c myself. – Panda Pajama Jun 08 '14 at 14:23
  • Sorry! But I saw no connection to C# in your post. So if it is, please try to also specify your platform (WPF, ASP, Winforms) in a Tag! Ahh `Monotouch`, that had been missing! – TaW Jun 08 '14 at 14:32
  • @TaW: The monotouch tag was there from the beginning. The part that says that this is for "Xamarin.iOS" was also there from the beginning. I have added some clarifications in the text to ensure everybody understands this is c#. – Panda Pajama Jun 08 '14 at 14:36
  • Ok, let's agree that I was wrong ;-) – TaW Jun 08 '14 at 14:38

1 Answers1

4

In order to get keyboard events on a UIView, you need to adopt the UIKeyInput protocol.

To do this, first you have to decorate your view class with [Adopts("UIKeyInput")].

Then, you need to implement all the methods required by UIKeyInput:

    [Export("hasText")]
    bool HasText { get { return false; } }

    [Export("insertText:")] // Don't forget the colon
    void InsertText(string text) // This is what gets called on a key press
    {
    }

    [Export("deleteBackward")]
    void DeleteBackward()
    {
    }

Finally, you have to let iOS know that this can become a first responder (whatever that is):

    public override bool CanBecomeFirstResponder { get { return true; } }

And then you have to become the first responder when the view is coming up, for example on WillEnterForeground:

    view.BecomeFirstResponder();

Don't forget to stop being the first responder when the view is leaving focus, for example on DidEnterBackground:

    view.ResignFirstResponder();

Finally, it would be a good idea to implement inputView and have it return an empty UIView so the default keyboard won't come out:

    private UIView inputView;
    // ...

    inputView = new UIView(new RectangleF());

    // And somewhere else...
    [Export("inputView")]
    public new UIView InputView { get { return inputView; } }

Thanks to @radical in the chat for helping me figure this out.

This solution is not about getting key down and key up events, but about creating a new textbox. It would be awesome if somebody else pointed out how to actually get the lower-level key down and key up events, if that's even possible.

Panda Pajama
  • 1,283
  • 2
  • 13
  • 31
  • This is a very good answer, it worked great for me. You should mark it as the accepted answer. – Todd Jan 05 '17 at 21:19