はじめに
Visual Studio 2017 community(2017/9/22時点)のXamarin.iOSを使ってiOS向けのカスタムキーボードを作る方法およびコツをまとめます。
1.新規ソリューションを立ち上げる




2.キーボードのExtensionプロジェクトを追加する





そのまま次へを選択すると、Custom Keyboardのプロジェクトが追加されます。
3.キーボードのViewとそれを司るクラスファイルを作成する



ここで、KeyboardView.csを選択してください。
KeyboardView.csの最低限の編集を行います。
もともとのソースコードは、
using System;
using Foundation;
using UIKit;
namespace iOSCustomKeyboard
{
public partial class KeyboardView : UITableViewCell
{
public static readonly NSString Key = new NSString("KeyboardView");
public static readonly UINib Nib;
static KeyboardView()
{
Nib = UINib.FromName("KeyboardView", NSBundle.MainBundle);
}
protected KeyboardView(IntPtr handle) : base(handle)
{
// Note: this .ctor should not contain any initialization logic.
}
}
}
上のようになっていると思います。これを下のように書き換えてください。
using System;
using Foundation;
using UIKit;
namespace TestKeyboard
{
public partial class KeyboardView : UIView
{
static KeyboardView()
{
}
protected KeyboardView(IntPtr handle) : base(handle)
{
}
}
}
namespaceと親クラスを変更するのを忘れないでください。




このタイミングでKeyboardView.designer.csを選択してnamespaceをTestKeyboardに変更してください。
using Foundation;
namespace TestKeyboard
{
[Register("KeyboardView")]
partial class KeyboardView
{
void ReleaseDesignerOutlets()
{
}
}
}
そうしたらKeyboardView.xibを開いてください。

これで下準備は完了です。
4.キーボードのViewをレイアウトする
引き続きKeyboardView.xibを編集します。

左上のVIEW ASがGenericとなっているので、iPhone6など自分のデザインしやすいものにしてください。






今度はBボタンを選択し、Aボタンと同じイベントハンドラに接続します。
すでに一度作ってあるイベントハンドラは候補から選択できます。
同様にしてNextボタンはPushNext、SpaceボタンはPushSpaceというイベントハンドラ名でコードと関連付けを行ってください。
結果KeyboardView.csはこのようになります。
using System;
using Foundation;
using UIKit;
namespace TestKeyboard
{
public partial class KeyboardView : UIView
{
static KeyboardView()
{
}
protected KeyboardView(IntPtr handle) : base(handle)
{
}
partial void PushKey(UIButton sender)
{
throw new NotImplementedException();
}
partial void PushNext(UIButton sender)
{
throw new NotImplementedException();
}
partial void PushSpace(UIButton sender)
{
throw new NotImplementedException();
}
}
}
ちなみにKeyboardView.designer.csの方は自動で編集が進み、このようになっています。
using Foundation;
using System;
using System.CodeDom.Compiler;
namespace TestKeyboard
{
[Register ("KeyboardView")]
partial class KeyboardView
{
[Outlet]
[GeneratedCode ("iOS Designer", "1.0")]
UIKit.UIButton AButton { get; set; }
[Outlet]
[GeneratedCode ("iOS Designer", "1.0")]
UIKit.UIButton BButton { get; set; }
[Outlet]
[GeneratedCode ("iOS Designer", "1.0")]
UIKit.UIButton NextButton { get; set; }
[Outlet]
[GeneratedCode ("iOS Designer", "1.0")]
UIKit.UIButton SpaceButton { get; set; }
[Action ("PushKey:")]
[GeneratedCode ("iOS Designer", "1.0")]
partial void PushKey (UIKit.UIButton sender);
[Action ("PushNext:")]
[GeneratedCode ("iOS Designer", "1.0")]
partial void PushNext (UIKit.UIButton sender);
[Action ("PushSpace:")]
[GeneratedCode ("iOS Designer", "1.0")]
partial void PushSpace (UIKit.UIButton sender);
void ReleaseDesignerOutlets ()
{
if (AButton != null) {
AButton.Dispose ();
AButton = null;
}
if (BButton != null) {
BButton.Dispose ();
BButton = null;
}
if (NextButton != null) {
NextButton.Dispose ();
NextButton = null;
}
if (SpaceButton != null) {
SpaceButton.Dispose ();
SpaceButton = null;
}
}
}
}
最後にボタンがわかるように背景色を設定しましょう。
Viewやボタンを選択してプロパティのWidgetのViewのBackground項目を設定すると背景色を変更できます。
レイアウト周りの下準備は以上です。
5.コーディング
KeyboardView.csを開きます。まずは下のように追記してください。
using System;
using Foundation;
using UIKit;
namespace TestKeyboard
{
public interface KeyboardViewDelegate
{
void selectKey(string key);
void selectNext();
void selectSpace();
}
public partial class KeyboardView : UIView
{
public KeyboardViewDelegate delegate_;
static KeyboardView()
{}
protected KeyboardView(IntPtr handle) : base(handle)
{}
public override void AwakeFromNib()
{
AButton.Layer.CornerRadius = 10;
BButton.Layer.CornerRadius = 10;
NextButton.Layer.CornerRadius = 10;
SpaceButton.Layer.CornerRadius = 10;
}
partial void PushKey(UIButton sender)
{
delegate_.selectKey(sender.CurrentTitle);
}
partial void PushNext(UIButton sender)
{
delegate_.selectNext();
}
partial void PushSpace(UIButton sender)
{
delegate_.selectSpace();
}
}
}
続いて、KeyboardViewController.csを編集します。
まずは余計なものを消して綺麗にしましょう。
using System;
using ObjCRuntime;
using Foundation;
using UIKit;
namespace TestKeyboard
{
public partial class KeyboardViewController : UIInputViewController
{
protected KeyboardViewController(IntPtr handle) : base(handle)
{}
public override void DidReceiveMemoryWarning()
{
base.DidReceiveMemoryWarning();
}
public override void UpdateViewConstraints()
{
base.UpdateViewConstraints();
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
}
public override void TextWillChange(IUITextInput textInput)
{}
public override void TextDidChange(IUITextInput textInput)
{}
}
}
綺麗にできたら下のように追記してください。
using System;
using ObjCRuntime;
using Foundation;
using UIKit;
namespace TestKeyboard
{
public partial class KeyboardViewController : UIInputViewController, KeyboardViewDelegate
{
KeyboardView kv;
protected KeyboardViewController(IntPtr handle) : base(handle)
{}
public override void DidReceiveMemoryWarning()
{
base.DidReceiveMemoryWarning();
}
public override void UpdateViewConstraints()
{
base.UpdateViewConstraints();
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
kv = UINib.FromName("KeyboardView", null).Instantiate(this, null)[0] as KeyboardView;
kv.delegate_ = this;
View.AddSubview(kv);
}
public override void TextWillChange(IUITextInput textInput)
{}
public override void TextDidChange(IUITextInput textInput)
{}
public void selectKey(string key)
{
TextDocumentProxy.InsertText(key);
}
public void selectNext()
{
AdvanceToNextInputMode();
}
public void selectSpace()
{
TextDocumentProxy.InsertText(" ");
}
}
}
コーディングは以上です。
6.実行
レイアウトをしたサイズのiPhoneをシミュレータで指定して実行しましょう。真っ白な画面が出てくると思います。
ホームボタンを押すか、shift + command + H でホーム画面を表示して、環境設定を開き、一般->言語->キーボードから自作したiOSCustomKeyboardを追加しましょう。
リマインダアプリなどでキーボードの動作を確認できます。
7.終わりに
XamarinでのiOSカスタムキーボード開発の基礎の基礎ですが、なんとかやり方を確立できてよかったです。