LoginSignup
10
10

More than 5 years have passed since last update.

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

Last updated at Posted at 2013-02-27

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

10
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
10