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

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

內容目錄:

  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