7
8

More than 5 years have passed since last update.

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

Posted at

これの続き
UIButtonを押すとキーボードが出てくるようにする

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

右下の赤色のボタンを押すと ツールバー付きのキーボードが出てくるようにしたい

解決策

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

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を実装する方法
こちらを参照してinputAccessoryViewtoolbarを入れたら良さそうということはわかるが、UIButtonを拡張している場合,拡張したUIButtonにinputAccessoryViewが存在しているのかどうなのかがさっぱりわからなかった

Appleのドキュメントを確認

Apple 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?

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

private let accessoryView = AccessoryView()
class MessagesViewController : UIViewController {
    override var inputAccessoryView: AccessoryView {
        return accessoryView
    }
}

とりあえず拡張したUIButtonクラス内に入れたいツールバーを作って、inputAccessoryViewに入れることでできた :clap:

参考文献

【Swift4】キーボードの上にUIToolbarを実装する方法
How do I redeclare a property as read-write in UIResponder subclass with swift?

7
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
8