以下の2つの動作に合わせてキーボードを閉じるというシナリオを想定している。
- テキストフィールド(UITextField)での入力中にEnterを押した場合
- テキストフィールドでの入力中にキーボード以外の場所をタップした場合
StoryBoardメインで実装する場合
Enterを押した際の挙動は、UITextFieldの"Did End On Exit"イベントをバインドしたメソッド(以下の図ではonReturn:
)で制御する。
onReturn:
の実装は以下の通り。
- (IBAction)onReturn:(UITextField *)sender {
[sender resignFirstResponder];
}
resignFirstResponder
を呼び出すことで、現在イベントを最初に受け取る状態になっている(=ファーストレスポンダになっている)のを解除することができる。
UITextField
であれば、ファーストレスポンダ=キーボードが表示されている状態、と考えてよいのだろうか。(まだ正確な理解には至らず)
一方、キーボード以外の場所をタップした場合の挙動は、TapGestureRecognizer
を使って実装する。
XCodeの右下のパレットからTap Gesture Recognizer
を選択し、該当するビュー(キーボードを表示する際に下にあるビュー)にドラッグ&ドロップする。
その後、Tap Gesture Recognizer
をメソッド(以下の図ではonSingleTap:
)にバインドする。
onSingleTap:
の実装は以下の通り。
- (IBAction)onSingleTap:(UITapGestureRecognizer *)sender {
[self.view endEditing:YES];
}
UIView
のendEditing:
を呼ぶと、自身のサブビューがファーストレスポンダであった場合にそれを解除してくれるようだ。
ファーストレスポンダとなるものが複数存在する場合(etc. テキストフィールドが複数)でも問題なく処理できるため、こちらを使った方がいろいろと楽なのかもしれない。
コードメインで実装する場合
Enterを押した際の挙動は、UITextFieldDelegate
のtextFieldShouldReturn:
メソッドで定義する。
delegateをセットする必要があるため、テキストフィールドをOutletとしてバインドする。
viewDidLoad
内でテキストフィールドのdelegateをセットする。
textFieldShouldReturn:
の実装は、StoryBoardの場合と殆ど変わらないが戻り値を要求されるためそこだけ変更する。
キーボード以外の場所をタップした場合の挙動は、UITapGestureRecognizer
を自前でセットすることで実装できる。
UITapGestureRecognizerインスタンス生成時に、タップ時に呼ばれるメソッド(以下の図ではonSingleTap:
)とレシーバ(以下の図ではself
)を指定する。
生成したUITapGestureRecognizerインスタンスは、addGestureRecognizer:
メソッドで、ViewController配下のビュー(=キーボードを表示する際に下にあるビュー)に追加する。
onSingleTap:
の実装は、StoryBoardの場合と変わらない。
追記
書いたあとに同内容の記事があることに気付くorz
こちらの記事の方が簡潔にまとまっています。
http://qiita.com/qt6hy/items/88fdd6c2c1485200ba97