Затем в вашем общем приложении в MainPage.xaml.cs вам просто нужно:

рабатываюXamarin.Forms заявка наiOS, Android а такжеUWP.

Я хотел бы подключиться к событиям аппаратной клавиатуры на уровне приложения (не на уровне отдельной страницы (потому что это приложение Xamarin.Forms)), чтобы, когда пользователь нажимает клавишу на клавиатуре, я мог вызывать действие в моем приложении.

На Android я сделал это с помощью следующего события наMainActivity:.

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

Есть ли эквивалент дляXamarin iOS?

Ответы на вопрос(3)

что у iOS нет такого метода. Во-первых, вам нужно понять, какие кнопки вы хотите захватить. Если вы хотите захватить кнопки громкости, то вы можете найти ответ здесь:https://forums.xamarin.com/discussion/29648/detect-volume-change-from-hardware-buttons

public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();

        //KVO for outputVolume
        var session = AVAudioSession.SharedInstance();
        var errorOrNull = session.SetActive (true);
        if (errorOrNull != null) {
            //TODO: ...handle it
        }
        session.AddObserver (this, "outputVolume", NSKeyValueObservingOptions.New, IntPtr.Zero);


    }

    public override void ObserveValue (NSString keyPath, NSObject ofObject, NSDictionary change, IntPtr context)
    {
                   //TODO: Filter as appropriate, error-handling, etc.
        var volume = (float) (change ["new"] as NSNumber);

        volumeLabel.Text = volume.ToString();
    }

Если вы хотите захватить события клавиатуры, вы должны подписаться на представление, которое отвечает за процесс ввода.

Вы можете использовать NotificationCenter для подписки на все представления, которые могут обрабатывать ввод и получать уведомления в одном месте.

NSNotificationCenter.DefaultCenter.AddObserver (UITextField.TextFieldTextDidChangeNotification, (notification) =>
{
    Console.WriteLine ("Character received! {0}", notification.Object == TextField);
});

и XamForms. Вот как я решил это в Xamarin Forms 3.0.0.482510 / Xamarin.iOS 11.10 (это немного отличается от ответа Кевина выше, потому что я хотел обработать его в общем проекте xaml XamForms, а не в проекте iOS):

В своем проекте iOS (например, с общим проектом Xamarin Forms в решении с именем MobileProject) создайте новый класс:

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

[assembly: ExportRenderer(typeof(MobileProject.MainPage), typeof (com.YourCompany.iOS.KeyboardHookRenderer))]
namespace com.YourCompany.iOS
{
public class KeyboardHookRenderer : PageRenderer
{
    private string _RecvValue = string.Empty;

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

    protected override void OnElementChanged(VisualElementChangedEventArgs e)
    {
        base.OnElementChanged(e);
        string key = string.Empty;
        var selector = new ObjCRuntime.Selector("KeyRecv:");
        UIKeyCommand accelerator1 = UIKeyCommand.Create((NSString)"1", 0, selector);
        AddKeyCommand(accelerator1);
        UIKeyCommand accelerator2 = UIKeyCommand.Create((NSString)"2", 0, selector);
        AddKeyCommand(accelerator2);
        UIKeyCommand accelerator3 = UIKeyCommand.Create((NSString)"3", 0, selector);
        AddKeyCommand(accelerator3);

        ... etc as many as you need or use a loop based on key id...
    }

    [Export("KeyRecv:")]
    public void KeyRecv(UIKeyCommand cmd)
    {
        if (cmd == null)
            return;
        var inputValue = cmd.Input;
        if (inputValue == "\n" || inputValue == "\r")
        {
            ((MobileProject.MainPage) Element)?.HandleHardwareKeyboard(_RecvValue);
            _RecvValue = string.Empty;
        }
        else
        {
            _RecvValue += inputValue;
        }
    }
}
}

Затем в вашем общем приложении в MainPage.xaml.cs вам просто нужно:

/// <summary>
/// Handle hardware keys (from KeyboardHookRender.cs in iOS project)
/// </summary>
/// <param name="keys">Keys sent, including trailing Cr or Lf</param>
public void HandleHardwareKeyboard(string keys)
{
    SomeTextbox.Text = keys;
    // Whatever else you need to do to handle it
}
Решение Вопроса

KeyCommands отслеживать нажатие клавиши с аппаратной клавиатуры.

keyCommands

Объект респондента, который поддерживает аппаратные команды клавиатуры, может переопределить это свойство и использовать его для возврата массива объектов UIKeyCommand, которые он поддерживает. Каждый ключевой объект команды представляет последовательность клавиатуры для распознавания и метод действия респондента, чтобы вызвать в ответ.

Ключевые команды, которые вы возвращаете из этого метода, применяются ко всей цепочке респондента. Когда нажата комбинация клавиш, соответствующая объекту команды клавиш, UIKit обходит цепочку респондента в поисках объекта, который реализует соответствующий метод действия. Он вызывает этот метод для первого найденного объекта, а затем останавливает обработку события.

В Xamarin.forms вы должны создать собственный рендер дляContentPage на платформе iOS. Затем ключевые команды могут быть добавлены в этот рендерер страниц.

Если вы хотите, чтобы нажатия клавиш могли обрабатываться ViewController (Page), а не только элементами управления вводом (например, Entry), используйтеcanBecomeFirstResponder чтобы позволить viewcontroller стать первым респондентом.

Например, пользовательский рендер ContentPage на платформе iOS может выглядеть так:

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;
            }
        }
    }
}

Обратите внимание на эту строку, используяtypeof(ContentPage) в качестве параметра обработчика, вам не нужно ничего менять в вашем PCL:

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

 Kevin Li22 нояб. 2017 г., 09:39
@ user1, если мой ответ полезен, можешь принять его? Это важно для меня!
 user123 нояб. 2017 г., 13:28
Я опробовал этот метод, но в вашем примере вы не проходитеKey или жеString в качестве аргументов. Можно ли передавать аргументы, используя эту технику? как мне нужно знать, какая кнопка была нажата

Ваш ответ на вопрос