是否可以在应用程序级别挂钩硬件键盘事件?

use*_*er1 7 c# xamarin.ios ios xamarin xamarin.forms

我正在Xamarin.FormsiOSAndroid和开发应用程序UWP

我想在应用程序级别(而不是单个页面级别(因为它是一个 Xamarin.Forms 应用程序))挂钩硬件键盘事件,以便当用户按下键盘上的某个键时,我可以在我的应用程序中调用一个操作。

在 Android 上,我使用以下事件在MainActivity:.

public override bool OnKeyUp([GeneratedEnum] Keycode keyCode, KeyEvent e)
{
    //process key press
    return base.OnKeyUp(keyCode, e);
}
Run Code Online (Sandbox Code Playgroud)

有等价的Xamarin iOS吗?

Kev*_* Li 5

您可以使用KeyCommands来跟踪从硬件键盘按下的键。

按键命令

支持硬件键盘命令的响应器对象可以重新定义此属性并使用它返回它支持的 UIKeyCommand 对象数组。每个按键命令对象代表要识别的键盘序列和响应者要调用的动作方法。

您从此方法返回的关键命令将应用于整个响应者链。当按下与按键命令对象匹配的组合键时,UIKit 会遍历响应者链,寻找实现相应操作方法的对象。它在它找到的第一个对象上调用该方法,然后停止处理该事件。

在 Xamarin.forms 中,您必须在 iOS 平台上为ContentPage创建自定义呈现器。然后可以在该页面渲染器中添加键盘命令。

如果您希望按键可以由 ViewController(Page) 处理,而不仅仅是输入控件(例如 Entry),请使用canBecomeFirstResponder使 ViewController 成为第一响应者。

比如iOS平台的ContentPage自定义渲染器可以是这样的:

using System;
using Foundation;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using KeyCommandsInXamarinForms.iOS;

[assembly: ExportRenderer(typeof(ContentPage), typeof(MyCustomPageRenderer))]
namespace KeyCommandsInXamarinForms.iOS
{
    public class MyCustomPageRenderer : PageRenderer
    {
        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);

            if (e.OldElement != null || Element == null)
            {
                return;
            }

            //Create your keycommand as you need.
            UIKeyCommand keyCommand1 = UIKeyCommand.Create(new NSString("1"), UIKeyModifierFlags.Command, new ObjCRuntime.Selector("Action:"));
            UIKeyCommand keyCommand2 = UIKeyCommand.Create(new NSString("\t"), 0, new ObjCRuntime.Selector("Action:"));
            //Add your keycommands
            this.AddKeyCommand(keyCommand1);
            this.AddKeyCommand(keyCommand2);
        }

        [Export("Action:")]
        private void Excute(UIKeyCommand keyCommand)
        {
            Console.WriteLine(String.Format("key pressed - {0}", keyCommand.Value);
        }


        //Enable viewcontroller to become the first responder, so it is able to respond to the key commands.
        public override bool CanBecomeFirstResponder
        {
            get
            {
                return true;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意这一行,typeof(ContentPage)用作处理程序参数,然后您无需更改 PCL 中的任何内容:

[assembly: ExportRenderer(typeof(ContentPage), typeof(MyCustomPageRenderer))]