タッチを検知したいとき、ビューコントローラに実装するのは簡単。
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
この4メソッドをビューコントローラに実装するだけ。
ただ単にソースファイルに書くだけ。delegateの指定なども不要。
このメソッドは UIResponder に定義されている。UIViewControllerはその子孫クラスなので、そのまま書いてオーバーライドできる。
たとえば、テキストフィールド以外をタッチしたときにキーボードを閉じたいときは
以下のように実装する。
//XXX.h
@property (weak, nonatomic) IBOutlet UITextField *textField;
//XXX.m
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
if (touch.view != self.textField) {
[self.textField resignFirstResponder];
}
}
スクロールビューとタッチイベント
スクロールビューを使っているときは、タッチイベントが受け取れない。(メソッドが呼ばれない)
スクロールビューがタッチイベントを受け取り(スクロール処理のため)、タッチイベントが子ビューに伝播されないためだ。
つまり、スクロールビューがfirstResponderになっている。
これに対処するためには、スクロールビューのタッチイベントを受け取ったとき、次のレスポンダーにイベントを伝播すればいいので
UIScrollViewのタッチイベントメソッドを実装すればいい。UIScrollViewはもちろん既存のクラスなので、カテゴリー拡張を使う。
//UIScrollView+TouchEvent.h
#import <UIKit/UIKit.h>
@interface UIScrollView (TouchEvent)
@end
//UIScrollView+TouchEvent.m
#import "UIScrollView+TouchEvent.h"
@implementation UIScrollView (TouchEvent)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[[self nextResponder] touchesBegan:touches withEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[[self nextResponder] touchesBegan:touches withEvent:event];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[[self nextResponder] touchesBegan:touches withEvent:event];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
[[self nextResponder] touchesBegan:touches withEvent:event];
}
@end
という感じである。
これをプロジェクトに追加し、スクロールビューを使っているすべてのファイルからインポートすればいい。
ただそれは面倒だし忘れそうなので、Prefixファイルに書いておくのがよいだろう。
//MyProject-Prefix.pch
#ifndef MyProject_MyProject_Prefix_pch
#define MyProject_MyProject_Prefix_pch
// Include any system framework and library headers here that should be included in all compilation units.
// You will also need to set the Prefix Header build setting of one or more of your targets to reference this file.
#import "UIScrollView+TouchEvent.h"
#endif
pchファイルに付いては別記事で。
PR