手勢識別UIGestureRecognizer

手勢識別 UIGestureRecognizer

  • 利用UIGestureRecognizer,能輕松識別用戶在某個view上面做的一些常見手勢
  • UIGestureRecognizer是一個抽象類,定義了所有手勢的基本行為,,使用它的子類才能處理具體手勢
  • 手勢分類
    • UITapGestureRecognizer(點按)
    • UIPinchGestureRecognizer(捏合)
    • UIPanGestureRecognizer(拖動)
    • UISwipeGestureRecognizer(輕掃)
    • UIRotationGestureRecognizer(旋轉)
    • UILongPressGestureRecognizer(長按)
/**
 手勢識別,是單獨添加到某一個視圖上的
 ===================================
 如果要同時支持多個手勢識別,需要設置手勢識別代理
 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
 {
        return YES;
 }
 ====================================
 UIPanGestureRecognizer         拖動手勢
 UIPinchGestureRecognizer       縮放手勢
 UIRotationGestureRecognizer    旋轉手勢
 都是通過transform設置視圖的形變
 一定要記住設置完transform之后,需要將對應的形變參數復位
 =====================================
 因為輕掃手勢要求用戶比較放松的掃動,因此最好不要將此手勢添加到某一個視圖上,會局限用戶的操作
 ->一般要添加到self.view上
 ->如果要監聽多個輕掃方向,需要添加多個輕掃手勢
 =====================================
 長按手勢一定要判斷狀態,否則方法會在手勢開始和結束的時候分別調用,方法會被調用兩次
 */
#import "ViewController.h"

@interface ViewController ()<UIGestureRecognizerDelegate>
@property (nonatomic, strong) UIImageView *imageView;
@end

@implementation ViewController
- (UIImageView *)imageView
{
    if(_imageView == nil){
        _imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 200, 400)];
        _imageView.image = [UIImage imageNamed:@"頭像1"];
        //默認不支持點擊的
        _imageView.userInteractionEnabled = YES;
        [self.view addSubview:_imageView];
    }
    return  _imageView;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    [self imageView];
    [self addLongPressGesture];
}

#pragma mark - 點按手勢(單擊,點擊)
- (void)addTapGesture
{
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap)];
    //設置手勢識別器對象的具體屬性
    // 連續敲擊2次
    tapGesture.numberOfTapsRequired = 2;
    // 需要2根手指一起敲擊
    tapGesture.numberOfTouchesRequired = 2;

    [self.imageView addGestureRecognizer:tapGesture];
}
- (void)tap
{
    NSLog(@"摸我了");
}

#pragma mark - 旋轉
- (void)addRotateGesture
{
    UIRotationGestureRecognizer *rotate = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotate:)];
    //設置代理,想同時執行多個手勢
    rotate.delegate = self;
    [self.imageView addGestureRecognizer:rotate];
}
- (void)rotate:(UIRotationGestureRecognizer *)recognizer
{
    //recognizer.view       手勢作用的視圖
    //recognizer.rotation   手勢的旋轉
    //累加旋轉之后,一定要將手勢識別的旋轉角度復位
    recognizer.view.transform = CGAffineTransformRotate(recognizer.view.transform, recognizer.rotation);
    // 將手勢識別中的旋轉角度復位
    recognizer.rotation = 0.0;          // 非常重要!
}

#pragma mark - 縮放-捏合
- (void)addPinchGesture
{
    UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinch:)];
    //設置代理,想同時執行多個手勢的時候
    pinch.delegate = self;
    [self.imageView addGestureRecognizer:pinch];
}
- (void)pinch:(UIPinchGestureRecognizer *)recognizer
{
    recognizer.view.transform = CGAffineTransformScale(recognizer.view.transform, recognizer.scale, recognizer.scale);
    //將縮放比例復位
    recognizer.scale = 1.0;
}

#pragma mark - 拖動手勢
- (void)addPanGesture
{
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
    [self.imageView addGestureRecognizer:pan];
}
- (void)pan:(UIPanGestureRecognizer *)recognizer
{
    CGPoint translation = [recognizer translationInView:self.imageView];
    recognizer.view.transform = CGAffineTransformTranslate(recognizer.view.transform, translation.x, translation.y);
    //給平移復位
    [recognizer setTranslation:CGPointZero inView:self.imageView];
}

#pragma mark - 輕掃手勢
- (void)addSwipeGesture
{
    //如果要監聽多個輕掃方向,需要提那家多個輕掃手勢
    //輕掃手勢默認支持向右的掃動方向
    UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)];
    //向左掃
    UISwipeGestureRecognizer *swipeLeft =[[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)];
    swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
    //因為輕掃手勢要求用戶比較放松的掃動,因此最好不要將此手勢添加到某一個視圖上,會局限用戶的操作
    [self.view addGestureRecognizer:swipe];
    [self.view addGestureRecognizer:swipeLeft];
}
- (void)swipe:(UISwipeGestureRecognizer *)recognizer
{
    CGPoint from = self.imageView.center;
    CGPoint to;
    if(recognizer.direction == UISwipeGestureRecognizerDirectionLeft){
        to = CGPointMake(-from.x, from.y);
    }else{
        to = CGPointMake(3 * from.x, from.y);
    }

    [UIView animateWithDuration:0.25 animations:^{
        self.imageView.center = to;
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:0.25 animations:^{
            self.imageView.center = from;
        }];
    }];
}

#pragma mark - 長按手勢
- (void)addLongPressGesture
{
    UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
    [self.imageView addGestureRecognizer:longPress];
}
- (void)longPress:(UILongPressGestureRecognizer *)recognizer
{
    //判斷手勢狀態,長按手勢一定要判斷狀態,否則方法會在手勢開始和結束時分別調用!方法會被調用兩次
    if(recognizer.state == UIGestureRecognizerStateBegan){
        [UIView animateWithDuration:0.25 animations:^{
            self.imageView.alpha = 0.25;
        } completion:^(BOOL finished) {
            self.imageView.alpha = 1.0;
        }];
    }
}
#pragma mark - 手勢識別代理方法
//同時識別兩個手勢
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}

// 是否允許開始觸發手勢
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    return YES;
}

// 是否允許接收手指的觸摸點
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
    // 獲取當前的觸摸點
    CGPoint curP = [touch locationInView:self.imageView];
    if (curP.x < self.imageView.bounds.size.width * 0.5) {
        return NO;
    }else{
        return YES;
    }
}

@end


//手勢識別狀態
typedef NS_ENUM(NSInteger, UIGestureRecognizerState) {
    // 沒有觸摸事件發生,所有手勢識別的默認狀態
    UIGestureRecognizerStatePossible,
    // 一個手勢已經開始但尚未改變或者完成時
    UIGestureRecognizerStateBegan,
    // 手勢狀態改變
    UIGestureRecognizerStateChanged,
    // 手勢完成
    UIGestureRecognizerStateEnded,
    // 手勢取消,恢復至Possible狀態
    UIGestureRecognizerStateCancelled,
    // 手勢失敗,恢復至Possible狀態
    UIGestureRecognizerStateFailed,
    // 識別到手勢識別
    UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded
};
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容