Re:ゼロから始めるキーボード製作 in Swift (１日目)

最近、「Re:ゼロから始める異世界生活」を観たんですが、かなり良かったです。
夜観始めて、気づいたら朝になっていました。レムりんたまらん。
「鉄血のオルフェンズ」も二期が始まって個人的に注目しています。

...余談が過ぎました。本題に入りましょう。

# アプリ内で使える独自のキーボードが欲しい...

iOS側でもともと用意されている *Number Pad* や *Decimal Pad* は決定キーが無かったり、余計なキーが付いていたりと何かと不便なケースがあります。
「*CustomKeyboard* で実装しよう」と考えると、いちいちユーザーに設定から許可をしてもらわないと使えなかったりでそれも不便。

で、見つけたのが以下。

[Custom Views for Data Input - Apple Developers Guide -](https://developer.apple.com/library/content/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/InputViews/InputViews.html)

なるほど、`UITextField.inputView` に`UIView`突っ込めばいいのか。
作っていきましょうか。一から... **いいえ、ゼロから！**

## 作ってみる
### UIの作成
1. Storyboardの準備
あらかじめ`Main Storyboard` に`UITextField`を準備して`ViewController`側へOutletしておいてください。
<img width="800" alt="" src="https://cl.ly/2I2I0y053X1a/Storyboard.png">

1. カスタムビューの準備

以下の2つのファイルを作成します

* `CustomKeyboard.xib`
* `CustomKeyboard.swift`

`CustomKeyboard.xib`へ適当にボタンを配置します。
(`File's Owner` に`CustomKeyboard`を設定してください)
<img width="800" alt="" src="https://cl.ly/000P3l2a3u1m/XIBFile.png">

`CustomKeyboard.swift`の内容は以下で。

```swift
class CustomKeyboard: UIView {
  
    // コードから呼ばれるInitializer
    override init(frame: CGRect) {
        super.init(frame: frame)
        initView()
    }
    
    // xib/storyboardから呼ばれるInitializer
    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        initView()
    }
    
    func initView() {
        // xibファイルからViewを読み込みます
        let view = Bundle.main.loadNibNamed("CustomKeyboard",
                                            owner: self,
                                            options: nil)?.first as! UIView
        addSubview(view)
        
        // AutoLayoutの制約関連を設定
        view.translatesAutoresizingMaskIntoConstraints = false
        let bindings = ["view": view]
        addConstraints(NSLayoutConstraint.constraints(
            withVisualFormat: "H:|[view]|",
            options: NSLayoutFormatOptions(rawValue: 0),
            metrics: nil,
            views: bindings))
        addConstraints(NSLayoutConstraint.constraints(
            withVisualFormat: "V:|[view]|",
            options: NSLayoutFormatOptions(rawValue: 0),
            metrics: nil,
            views: bindings))
    }
}
```
これでUIの準備は完了です。


### ViewController側の設定

あとは`ViewController`で`UITextField.inputView`へ先ほど作成した`CustomKeyboard`を代入すれば完了です。

```swift
class ViewController: UIViewController {

    @IBOutlet weak var textField: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setKeyboard()
    }
    
    func setKeyboard() {
        // viewを生成
        let keyboardView = CustomKeyboard()

        // サイズを決めます
        let frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height / 3)
        keyboardView.frame = frame

        // 代入
        textField.inputView = keyboardView
    }
...
```

あとは実行してみてください。


## 呼び出してみる

あとは、エミュレータで実行してTextFieldをタップしてみるだけです。
以下のように下からにゅっとViewが表示されます。

<img width="300" src="https://cl.ly/3b2U1l3A0X1z/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202016-10-24%203.54.19.png">


## うん、ちょっと待てよ...

キーボードは表示できたんですが、このままじゃ入力できません。
押しても何も反応しないんじゃ。

そこも自前で実装しなきゃなりません。詳しくは次回やっていきましょう。

大雑把に説明すると...

* `CustomKeyboard.swift`に`delegate`を定義
* `ViewController`側で受け取って`UITextField.text`の値を書き換える

てな感じです。