UIButtonでtoolbar付きのKeyboardを出したい

これの続き
[UIButtonを押すとキーボードが出てくるようにする](https://qiita.com/nakagawa1017/items/ff37020fc01d39c51805)

UItextFiledだったら`inputAccessoryView`に入れたいツールバーを入れたらいいとのことだったが、UIButtonを拡張した場合ちょっと詰まったのでメモ

|右下の赤色のボタンを押すと|ツールバー付きのキーボードが出てくるようにしたい|
|---|---|
|![](https://qiita-image-store.s3.amazonaws.com/0/176479/d101efb1-5ddc-e629-bd9f-5a071100ccc9.png)|![](https://qiita-image-store.s3.amazonaws.com/0/176479/55805f79-5f9f-24e8-bd6e-59203aeae448.png)| 

## 解決策
このクラスを使ったボタンであれば押すとキーボードが出てくるようになっています

```Swift
class RespondingButton: UIButton, UIKeyInput {

    override var canBecomeFirstResponder: Bool {
        return true
    }

    let toolbar :UIToolbar = {
        let toolbar = UIToolbar()
        let flexibleItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action: nil)
        let okButton: UIBarButtonItem = UIBarButtonItem(title: "OK", style: UIBarButtonItem.Style.plain, target: self, action: #selector(TargetListViewController.openLeftMenu))
        let cancelButton: UIBarButtonItem = UIBarButtonItem(title: "CANCEL", style: UIBarButtonItem.Style.plain, target: self, action: #selector(TargetListViewController.openLeftMenu))
        // アイテムを配置
        toolbar.setItems([flexibleItem, okButton, flexibleItem, cancelButton, flexibleItem], animated: true)
        // ツールバーのサイズを指定
        toolbar.sizeToFit()

        return toolbar
    }()

    //private let accessoryView = UIView()
    override var inputAccessoryView: UIView {
        return self.toolbar
    }
    var hasText: Bool = true
    func insertText(_ text: String) {}
    func deleteBackward() {}
}

```

## 調査の経緯
[【Swift4】キーボードの上にUIToolbarを実装する方法](https://qiita.com/siropaca/items/2770a7793c987e2bdb70)
こちらを参照して`inputAccessoryView`に`toolbar`を入れたら良さそうということはわかるが、UIButtonを拡張している場合,拡張したUIButtonに`inputAccessoryView`が存在しているのかどうなのかがさっぱりわからなかった

### Appleのドキュメントを確認
[Apple inputAccessoryView](https://developer.apple.com/documentation/uikit/uiresponder/1621119-inputaccessoryview)
こちらを参照する

> 受信者が最初のレスポンダになったときに表示されるカスタム入力アクセサリビュー

UIButtonクラスの親クラスは`UIResponder`を継承しているので`inputAccessoryView`を持っているはず・・・
なのに

```
button.inputAccessoryView = toolbar
```
でエラーを吐かれてしまう

説明をよく読んでみると

```
This property is typically used to attach an accessory view to the system-supplied keyboard 
that is presented for UITextField and UITextView objects.

The value of this read-only property is nil. 
If you want to attach custom controls to a system-supplied input view 
(such as the system keyboard) or to a custom input view (one you provide in the inputView property), redeclare this property as read-write in a UIResponder subclass. 
You can then use this property to manage a custom accessory view. 
When the receiver becomes the first responder, the responder infrastructure attaches the accessory view to the appropriate input view before displaying it.
```

つまりこのプロパティは *read-only property* です
カスタム入力ビューで使うならこのプロパティをUIResponderサブクラスの読み書き可能として再宣言してねとのことでした

再宣言・・？ :thinking: 

## 再宣言のやり方を調べる
こちらの文献を参考にしました
[How do I redeclare a property as read-write in UIResponder subclass with swift?](https://stackoverflow.com/questions/26841205/how-do-i-redeclare-a-property-as-read-write-in-uiresponder-subclass-with-swift)

こういうふうにすれば良さそうということがわかった

```Swift
private let accessoryView = AccessoryView()
class MessagesViewController : UIViewController {
    override var inputAccessoryView: AccessoryView {
        return accessoryView
    }
}
```
とりあえず拡張したUIButtonクラス内に入れたいツールバーを作って、`inputAccessoryView`に入れることでできた　:clap: 


# 参考文献
[【Swift4】キーボードの上にUIToolbarを実装する方法](https://qiita.com/siropaca/items/2770a7793c987e2bdb70)
[How do I redeclare a property as read-write in UIResponder subclass with swift?](https://stackoverflow.com/questions/26841205/how-do-i-redeclare-a-property-as-read-write-in-uiresponder-subclass-with-swift)