Help us understand the problem. What is going on with this article?

UIButtonを押すとキーボードが出てくるようにする

More than 1 year has passed since last update.

はじめに

UIButtonを押すとキーボードが出てくるようにしたい

参考文献によるとUIButtonを継承、UIKeyInputプロトコルを適合させたものを使うといいとのことだった

class RespondingButton: UIButton, UIKeyInput {

    override var canBecomeFirstResponder: Bool {
        return true
    }

    var hasText: Bool = true
    func insertText(_ text: String) {}
    func deleteBackward() {}
}

Appleの文献を読む

canBecomeFirstResponderとはなにか

まずoverrideさせているcanBecomeFirstResponderについて調べてみる
Apple canBecomeFirstResponder

このオブジェクトが最初のレスポンダになることができるかどうかを示すブール値を返します。

このメソッドはデフォルトでfalseを返します。サブクラスはこのメソッドをオーバーライドし、trueを返してファーストレスポンダになることができるようにする必要があります。
現在アクティブなビュー階層にないビューでは、このメソッドを呼び出さないでください。結果は未定義です。

そもそもこのプロパティはどこにいるかというと、
UIButton←UIControl←UIView←UIResponderをめぐりUIResponder内にいることがわかる
UIResponderとはイベントに応答し処理するための抽象インタフェースのこと

つまり、UIButtonではこのcanBecomeFirstResponderプロパティはデフォルトでfalseになっているので、オーバーライドしてプロパティを書き直す必要があるとのことだ

UIKeyInputプロトコルを調べる

UIKeyInputUITextInputTraitsを継承しているプロパティ
こいつを適合させると下記3つのプロパティとメソッドを書く必要がある

public protocol UIKeyInput : UITextInputTraits {


    public var hasText: Bool { get }


    public func insertText(_ text: String)

    public func deleteBackward()
}

Appleのドキュメントによると

UIResponderのサブクラスが単純なテキスト入力を実装するために使用する一連のメソッド。

とのこと

このサブクラスのインスタンスが最初のレスポンダの場合、システムキーボードが表示されます。
このプロトコルを採用しているクラスでは、利用可能なキーボードと言語のごく一部しか利用できません。

UITextFieldの定義を見てみると下記のようにこのプロトコルが適合されている

@available(iOS 2.0, *)
open class UITextField : UIControl, UITextInput, NSCoding, UIContentSizeCategoryAdjusting {

だから自動でキーボードが出てくるようになっているのだと思う
おそらくcanBecomeFirstRespondertrueになっているのではないかと思う(ソースは調査中)

3つのメソッドとプロパティを調べる

Appleのドキュメントの下のプロパティメソッド一覧にRequired.とついていて親切だなと思った

func insertText(String)

表示されているテキストに文字を挿入します。 必須。
カーソルに対応するインデックスにあるクラスのバッキングストアに文字テキストを追加して、テキストを再表示します。

Apple insertText(_:)

deleteBackward()

表示されているテキストから文字を削除します。
クラスのバッキングストアからカーソルの直前の文字を削除して、テキストを再表示します。

hasText

テキスト入力オブジェクトにテキストがあるかどうかを示すブール値。
バッキングストアにテキストコンテンツがある場合はtrue、そうでない場合はfalse
Apple hasText

この押すとキーボードが出てくるボタンをつくるのに
テキスト入力オブジェクトにテキストがあるかどうかを示すブール値はtrue
表示されているテキストから文字を削除する → とくに設定しない
表示されているテキストに文字を挿入する → 特に設定しない

というようにしているとのことだった
(使い方はいまいち把握できてないので今度調査する)

UITextInputTraitsを調べる

UIKeyInputの親プロトコル?のUITextInputTraitsも気になったので調べた

テキストオブジェクトへのキーボード入力に関連する機能を定義するメソッドのコレクション
カスタムテキストオブジェクトがキーボード入力をサポートするには、テキスト入力管理システムと正しく対話するためにこのプロトコルを採用する必要があります。 UITextFieldクラスとUITextViewクラスは自動的にこのプロトコルをサポートします。

プロパティを見た感じキーボードの外観や、入力に関する細かい設定ができる

UITextInputTraits

たとえば今回の参考文献で紹介されていたボタンを押して
数字を押す形式のキーボードを出したい場合は下記のように設定を変更できる

プロトコルが定義されているところを見て

optional→適合先でこのプロパティを書いても書かなくてもどっちでも良い
public → クラス外からでも参照できる
var → 変数
keyboardType → keyboardTypeという名前のプロパティ
UIKeyboardType → UIKeyboardTypeという型のものをがはいっている
{ get set } → このプロパティから値を取れるし入れることができる

public protocol UITextInputTraits : NSObjectProtocol {

~~~~ 省略 ~~~~
optional public var keyboardType: UIKeyboardType { get set } // default is UIKeyboardTypeDefault
~~~~ 省略 ~~~

UIKeyboardTypeは下記のように定義されているので、このなかのどれかのcaseを入れてあげればいい

public enum UIKeyboardType : Int {


    case `default` // Default type for the current input method.

    case asciiCapable // Displays a keyboard which can enter ASCII characters

    case numbersAndPunctuation // Numbers and assorted punctuation.

    case URL // A type optimized for URL entry (shows . / .com prominently).

    case numberPad // A number pad with locale-appropriate digits (0-9, ۰-۹, ०-९, etc.). Suitable for PIN entry.

    case phonePad // A phone pad (1-9, *, 0, #, with letters under the numbers).

    case namePhonePad // A type optimized for entering a person's name or phone number.

プロトコルで定義されているプロパティに適合先で値を入れればいいので下記のように書き直す

class RespondingButton: UIButton, UIKeyInput {

    override var canBecomeFirstResponder: Bool {
        return true
    }

    var hasText: Bool = true
    func insertText(_ text: String) {}
    func deleteBackward() {}
    var keyboardType: UIKeyboardType = .numberPad

}

参考文献

iOS - UIButton become first responder to open keyboard

nakagawa1017
iOSエンジニアしてます 好きなもの Adobe.Ai.AE.Ps/Sketch/Blender/デジタルファブリケーション
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away