pan手勢監聽對view的上下左右滑動,利用關聯物件在block中觸發view的點選事件(附手勢大全)

wuhao丶發表於2017-10-25

內容目錄:

  1. 在block中觸發view的點選事件
  2. 利用pan手勢,監聽對view的上下左右滑動
  3. 各種手勢的簡單實現
  4. 解決手勢衝突

一、在block中觸發view的點選事件

首先建立一個UIView的分類,下面是標頭檔案中的程式碼。

/****************UIView+WHAddTap.h**********************/

#import <UIKit/UIKit.h>

// 定義點選view的block
typedef void(^TapActionBlock)(UITapGestureRecognizer *tapGesture);

@interface UIView (WHAddTap)

// 點選view時觸發此方法
- (void)wh_addTapActionWithBlock:(TapActionBlock)block;

@end複製程式碼

下面是具體實現程式碼,需要用到runtime的關聯物件,所以別忘了引入標頭檔案#import

/****************UIView+WHAddTap.m**********************/

#import "UIView+WHAddTap.h"
#import <objc/runtime.h>

@implementation UIView (WHAddTap)

- (void)wh_addTapActionWithBlock:(TapActionBlock)block {
    // 關聯物件獲取手勢tap,_cmd是key值,代表此方法名
    UITapGestureRecognizer *tap = objc_getAssociatedObject(self, _cmd);
    if (!tap) {
        // 首次點選獲取不到關聯物件,建立手勢並繫結觸發方法
        tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(actionForTap:)];
        // 新增手勢
        [self addGestureRecognizer:tap];
        // 運用runtime,set手勢tap,這樣下次點選的時候 外面的tap就存在了
        objc_setAssociatedObject(self, @selector(wh_addTapActionWithBlock:), tap, OBJC_ASSOCIATION_RETAIN);
    }
     // key是手勢觸發的方法名,關聯block
    objc_setAssociatedObject(self, @selector(actionForTap:), block, OBJC_ASSOCIATION_COPY);
}

// tap手勢的實現
- (void)actionForTap:(UITapGestureRecognizer *)tap {
    if (tap.state == UIGestureRecognizerStateRecognized) {
        // _cmd就是此方法名,利用這個key拿到上面的方法關聯的block
        TapActionBlock block = objc_getAssociatedObject(self, _cmd);
        if (block) {
            block(tap);
        }
    }
}

@end複製程式碼

應用如下

// 在需要使用的地方引入標頭檔案
#import "UIView+WHAddTap.h"

// 直接用view物件呼叫分類中的方法,在block中寫程式碼
[view wh_addTapActionWithBlock:^(UITapGestureRecognizer *tapGesture) {

    NSLog(@"點選了這個view");
}];複製程式碼

二、利用pan手勢,監聽對view的上下左右滑動

簡單暴力,直接上程式碼

    // 給view新增pan手勢
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(directionPan:)];
    [view addGestureRecognizer:pan];

// 監聽上下左右滑動的方法
- (void)directionPan:(UIPanGestureRecognizer *)pan {
    CGPoint movePoint = [pan translationInView:pan.view];
    [pan setTranslation:CGPointZero inView:pan.view];

    CGFloat absX = fabs(movePoint.x);
    CGFloat absY = fabs(movePoint.y);

    if (absX > absY ) {
        if (movePoint.x<0) {
            NSLog(@"向左滑動");

        }else{
            NSLog(@"向右滑動");

        }

    } else if (absY > absX) {
        if (movePoint.y<0) {
            NSLog(@"向上滑動");

        }else{
            NSLog(@"向下滑動");

        }
    }
}複製程式碼

三、各種手勢的簡單實現

    // 1. 縮放手勢pinch
    UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinch:)];
    [view addGestureRecognizer:pinch];

// 縮放手勢pinch觸發方法
- (void)pinch:(UIPinchGestureRecognizer *)pinch {
    self.tempView.transform = CGAffineTransformScale(self.tempView.transform, pinch.scale, pinch.scale);
    pinch.scale = 1;
}

/************************************************************/

    // 2. 點選手勢tap
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)];
    tap.numberOfTapsRequired = 1;    // 點選多少次才能觸發方法
    tap.numberOfTouchesRequired = 1; // 幾根手指點選
    [view addGestureRecognizer:tap];

// 點選手勢tap觸發方法 
- (void)tap:(UITapGestureRecognizer *)tap {
    NSLog(@"%@", tap.view);
}

/************************************************************/

    // 3. 長按手勢longPress
    UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
    longPress.minimumPressDuration = 2;  // 長按2秒觸發監聽方法
    longPress.allowableMovement = 5;  // 這個範圍內移動, 還是可以觸發方法
    [view addGestureRecognizer:longPress];

// 長按手勢longPress觸發方法
- (void)longPress:(UILongPressGestureRecognizer *)longPress {
    if (longPress.state == UIGestureRecognizerStateBegan) {
        NSLog(@"在這裡執行長按後的程式碼");
    }
}

/************************************************************/

    // 4. 輕掃手勢swipe
    // 向左
    UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)];
    swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
    [view addGestureRecognizer:swipeLeft];
    // 向右
    UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)];
    swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
    [view addGestureRecognizer:swipeRight];
    // 向上
    UISwipeGestureRecognizer *swipeUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)];
    swipeUp.direction = UISwipeGestureRecognizerDirectionUp;
    [view addGestureRecognizer:swipeUp];
    // 向上
    UISwipeGestureRecognizer *swipeDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)];
    swipeDown.direction = UISwipeGestureRecognizerDirectionDown;
    [view addGestureRecognizer:swipeDown];

// 輕掃手勢swipe觸發方法
- (void)swipe:(UISwipeGestureRecognizer *)swipe {
    if (swipe.direction == UISwipeGestureRecognizerDirectionRight) {
        NSLog(@"向右Swipe");

    } else if (swipe.direction == UISwipeGestureRecognizerDirectionLeft) {
        NSLog(@"向左Swipe");

    } else if (swipe.direction == UISwipeGestureRecognizerDirectionUp) {
        NSLog(@"向上Swipe");

    } else if (swipe.direction == UISwipeGestureRecognizerDirectionDown) {
        NSLog(@"向下Swipe");
    }
}

/************************************************************/

    // 5. 移動手勢pan
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
    [view addGestureRecognizer:pan];

// 移動手勢pan觸發方法
- (void)pan:(UIPanGestureRecognizer *)pan {
    CGPoint movePoint = [pan translationInView:pan.view];
    _tempView.transform = CGAffineTransformTranslate(_tempView.transform, movePoint.x, movePoint.y);
    [pan setTranslation:CGPointZero inView:pan.view];
}


/************************************************************/

    // 6. 旋轉手勢Rotation
    UIRotationGestureRecognizer *rotate = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotate:)];
    rotate.delegate = self;
    [view addGestureRecognizer:rotate];

// 旋轉手勢Rotation觸發方法
- (void)rotate:(UIRotationGestureRecognizer *)rotate {
    _tempView.transform = CGAffineTransformRotate(_tempView.transform, rotate.rotation);
    rotate.rotation = 0;
}複製程式碼

四、解決手勢衝突

// 首先遵守UIGestureRecognizerDelegate
@interface ViewController () <UIGestureRecognizerDelegate>

// 實現如下方法,return YES 解決手勢衝突問題
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}複製程式碼

後記

在block中觸發view的點選事件,主要運用的是關聯物件技巧,比較實用。
推薦簡單又好用的分類集合:WHKit

Github:github.com/remember17

轉載請註明出處:www.jianshu.com/p/4ff12ccfc…

相關文章