內容目錄:
- 在block中觸發view的點選事件
- 利用pan手勢,監聽對view的上下左右滑動
- 各種手勢的簡單實現
- 解決手勢衝突
一、在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…