オープンソースこねこね

Webプログラミングなどについてあれこれ。

UITextFieldやUITextViewでキーボードの外をタップしたらキーボードを閉じる

すでにいろいろやり方がネット上に書かれているが、自分の中では以下の方法に落ち着いたのでメモっておく。

まず、以下の記事で紹介されているようなFirstResponderを取得するメソッドをUIViewにカテゴリとして事前に実装しておく。

FirstResponderを探せ - Kazzzの日記

#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

あとはViewController上で以下のように実装する。

# XXHogeViewController.m

- (void)viewDidLoad {
    [super viewDidLoad];

    // タップを検知するためのGestureRecognizer。デリゲートで処理するように設定
    UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] init];
    gestureRecognizer.delegate = self;
    gestureRecognizer.cancelsTouchesInView = NO;
    [self.view addGestureRecognizer:gestureRecognizer];
}

// タップ時のデリゲートメソッド
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    UIView *touchedView = touch.view;
    UIView *firstResponderView = [self.view findFirstResponder];
    
    if (touchedView != firstResponderView) {
        // 現在編集中のViewと違う場所がタップされたときのみキーボードを閉じる
        [self.view endEditing:YES];
    }
    return YES;
}