UIGestureRecognizer blockを使用したtouchDown, touchUpのジェスチャーの実装


UITapGestureRecognizerのアクションはUIControlEventTouchUpInsideに割り当てられますが、UIControlEventTouchDown(最初に触れた時のイベント)も欲しかったので実装しました。
touchUpではUIControlEventTouchUpInside, UIControlEventTouchUpOutsideの判定も返るようにしています。
複数のジェスチャーが絡まない単純なものだったらこれで足りると思います。

## 使用例
```objectivec: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];
}
```

## 実装
```objectivec: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
```

```objectivec: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継承しているクラス)

```objectivec: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でライトな感じの使用方法にしたかったのでよしとします。