FirstResponderを探せ
Windowsの世界では「フォーカスを持つオブジェクト」という言い方をするが、Macの世界では「最初に応答するオブジェクト」という意味のFirstResponderを探したい場合がある。
一番よく使われるのが現在処理対象になっているNSResponderの派生クラス(殆どのUI)にresignFirstResponderメッセージを送る」ことだろう。
NSResponderとして振る舞うことができるUIはresignFirstResponderメッセージを受けることにより、非アクティブ状態に移行する。
それ自体も重要だが、もっと重要なのはこのメッセージを受けたUIText、UITextView等の入力が可能なユーザインタフェースはその時点で開かれているソフトウェアキーボードを閉じる振る舞いである。
iOSのプログラミングで最初に困るのことの一つが「一度表示されたソフトウェアキーボードを閉じる術がない」※という問題だが、resignFirstResponderをUIに送ることでこの問題を解決することができるのだ。
コーディング方法はいろいろあるが、典型的なのは同メッセージをVireControllerで集約して、現在アクティブ状態のUIに対してメッセージを再送付する処理である。
HogeTableViewController.m
- (BOOL)resignFirstResponder { UIView* responder = [[self tableView] findFirstResponder]; if ( responder ) { return [responder resignFirstResponder]; } return NO; }
findFirstResponderはUIView等のカテゴリで実装することで、インスタンスメソッドのように使えるだろう。
UIView+UIUtil.m
#import "UIView+UIUtil.h" @implementation UIView (UIUtil) - (UIView *)findFirstResponder { if ([self isFirstResponder]) { return self; } for (UIView *subView in [self subviews]) { if ([subView isFirstResponder]) { return subView; } if ([subView findFirstResponder]) { return [subView findFirstResponder]; } } return nil; } @end
※かくいう私もそうだ。