UITapGestureRecognizerのアクションはUIControlEventTouchUpInsideに割り当てられますが、UIControlEventTouchDown(最初に触れた時のイベント)も欲しかったので実装しました。
touchUpではUIControlEventTouchUpInside, UIControlEventTouchUpOutsideの判定も返るようにしています。
複数のジェスチャーが絡まない単純なものだったらこれで足りると思います。
使用例
Sample.m
- (void)viewDidLoad
{
[super viewDidLoad];
/* 設定 */
YSTapUpDownGestureRecognizer *tap = [[YSTapUpDownGestureRecognizer alloc] initWithTouchDown:^(YSTapUpDownGestureRecognizer *tapGesture, NSSet *touches, UIEvent *event){
NSLog(@"Down");
}touchUp:^(YSTapUpDownGestureRecognizer *tapGesture, NSSet *touches, UIEvent *event, BOOL isTouchUpInside){
NSLog(@"Up");
if (isTouchUpInside) {
NSLog(@"yes");
} else {
NSLog(@"no");
}
}];
[self.label addGestureRecognizer:tap];
}
実装
YSTapUpDownGestureRecognizer.h
#import <UIKit/UIKit.h>
@class YSTapUpDownGestureRecognizer;
typedef void(^YSTapUpDownGestureRecognizerTouchesDown) (YSTapUpDownGestureRecognizer *tapUpDownGesture, NSSet *touches, UIEvent *event);
typedef void(^YSTapUpDownGestureRecognizerTouchesUp) (YSTapUpDownGestureRecognizer *tapUpDownGesture, NSSet *touches, UIEvent *event, BOOL isTouchUpInside);
@interface YSTapUpDownGestureRecognizer : UIGestureRecognizer
- (id)initWithTouchDown:(YSTapUpDownGestureRecognizerTouchesDown)touchDown touchUp:(YSTapUpDownGestureRecognizerTouchesUp)touchUp;
@end
YSTapUpDownGestureRecognizer.m
#import "YSTapUpDownGestureRecognizer.h"
@interface YSTapUpDownGestureRecognizer ()
@property (nonatomic, copy) YSTapUpDownGestureRecognizerTouchesDown touchDown;
@property (nonatomic, copy) YSTapUpDownGestureRecognizerTouchesUp touchUp;
@end
@implementation YSTapUpDownGestureRecognizer
- (id)initWithTouchDown:(YSTapUpDownGestureRecognizerTouchesDown)touchDown touchUp:(YSTapUpDownGestureRecognizerTouchesUp)touchUp
{
if (self = [super init]) {
self.touchDown = touchDown;
self.touchUp = touchUp;
}
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if (self.touchDown) self.touchDown(self, touches, event);
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
/* 指が離れた位置が対象のビュー内か(UIControlEventTouchUpInsideを判定) */
UITouch *touch = [touches anyObject];
CGPoint touchPoint = [touch locationInView:self.view];
BOOL isTouchUpInside = CGRectContainsPoint(self.view.bounds, touchPoint);
if (self.touchUp) self.touchUp(self, touches, event, isTouchUpInside);
}
@end
その他
UIControlなら(or継承しているクラス)
sample.m
- (void)viewDidLoad
{
[self.button addTarget:self action:@selector(touchDown) forControlEvents:UIControlEventTouchDown];
[self.button addTarget:self action:@selector(touchUpInside) forControlEvents:UIControlEventTouchUpInside];
[self.button addTarget:self action:@selector(touchUpOutside) forControlEvents:UIControlEventTouchUpOutside];
}
- (void)touchDown
{
NSLog(@"down");
}
- (void)touchUpInside
{
NSLog(@"inside");
}
- (void)touchOutside
{
NSLog(@"outside");
}
みたいに出来ますが、blockとUIGestureRecognizerでライトな感じの使用方法にしたかったのでよしとします。