虚位以待(AD)
虚位以待(AD)
首页 > 软件编程 > IOS编程/Objective-C > iOS的手势识别器

iOS的手势识别器
类别:IOS编程/Objective-C   作者:码皇   来源:苏苏的iOS开发小站     点击:

如果想监听一个view上面的触摸事件,不使用手势实现的步骤(1) 自定义一个view(2) 实现view的touches方法,在方法内部实现具体处理代码

一. 监听触摸事件的做法

如果想监听一个view上面的触摸事件,不使用手势实现的步骤
(1). 自定义一个view
(2). 实现view的touches方法,在方法内部实现具体处理代码

通过touches方法监听view触摸事件,有很明显的几个缺点
(1). 必须得自定义view
(2). 由于是在view内部的touches方法中监听触摸事件,因此默认情况下,无法让其他外界对象监听view的触摸事件
(3). 不容易区分用户的具体手势行为

iOS 3.2之后,苹果推出了手势识别功能(Gesture Recognizer),在触摸事件处理方面,大大简化了开发者的开发难度

二. 手势识别器简介

为了完成手势识别,必须借助于手势识别器:UIGestureRecognizer

利用UIGestureRecognizer,能轻松识别用户在某个view上面做的一些常见手势

UIGestureRecognizer是一个抽象类,定义了所有手势的基本行为,使用它的子类才能处理具体的手势

UIGestureRecognizer的子类

UITapGestureRecognizer(敲击)
UIPinchGestureRecognizer(捏合,用于缩放)
UIPanGestureRecognizer(拖拽)
UISwipeGestureRecognizer(轻扫)
UIRotationGestureRecognizer(旋转)
UILongPressGestureRecognizer(长按)

三. UIGestureRecognizer的常见属性和方法

UIGestureRecognizer继承于NSObject

    // 初始化手势要触发的对象与事件- (instancetype)initWithTarget:(nullable id)target action:(nullable SEL)action// 添加手势要触发的对象与事件- (void)addTarget:(id)target action:(SEL)action;
    // 移除手势要触发的对象与事件- (void)removeTarget:(nullable id)target action:(nullable SEL)action;
    // 手势状态@property(nonatomic,readonly) UIGestureRecognizerState state;
    // 代理@property(nullable,nonatomic,weak) id delegate;
    // 手势是否可用,默认YES @property(nonatomic, getter=isEnabled) BOOL enabled;
    // 只读,手势所属的视图@property(nullable, nonatomic,readonly) UIView *view;
    // 默认YES.意思就是说一旦手势被识别,那么就调用[touchView touchesCancelled:withEvent]@property(nonatomic) BOOL cancelsTouchesInView;
    // 默认NO.意思就是再手势识别成功之前,touchObj还是要分发到touchView.// 设置为YES的时候就表示从手势识别成功之前touchObj不给touchView分发@property(nonatomic) BOOL delaysTouchesBegan;
    // 默认YES:在手势识别成功之前,touchesEnded不会被调用。// 设置为NO:在手势识别成功之前,touchesEnded会被调用@property(nonatomic) BOOL delaysTouchesEnded;
    // 当指定的识别器(调用者)识别失败,才去识别另一个识别器otherGestureRecognizer- (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer;
    // 获取手势识别器的触摸点- (CGPoint)locationInView:(nullable UIView*)view;
    // 获取手势识别器的触摸点个数- (NSUInteger)numberOfTouches;
    // 指定触摸点的位置- (CGPoint)locationOfTouch:(NSUInteger)touchIndex inView:(nullable UIView*)view;

四. UIGestureRecognizer代理

注意: 使用多个手势必须使用代理

    // 是否允许触发手势- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;
    // 是否允许多个同时支持多个手势,默认不允许,手势必须要设置代理- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
    // 这个方法在这两个gesture recognizers中的任意一个将堵塞另一个的触摸事件时调用,// 如果返回YES,则两个gesture recognizers可同时识别,// 如果返回NO,则并不保证两个gesture recognizers必不能同时识别,// 因为另外一个gesture recognizer的此方法可能返回YES。// 也就是说两个gesture recognizers的delegate方法只要任意一个返回YES,则这两个就可以同时识别;// 只有两个都返回NO的时候,才是互斥的。默认情况下是返回NO- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0);
    // 是否允许手势识别器识别失败的时候使用另一个识别器otherGestureRecognizer- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0);
    // 是否允许接收触摸点- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;
    // 是否允许接收长按点- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceivePress:(UIPress *)press;

五. UIGestureRecognizer的子类常见属性和方法

1. UITapGestureRecognizer(敲击)

    // 需要连续敲击几次才可触发,默认1次@property (nonatomic) NSUInteger numberOfTapsRequired;
    // 需要几根手指一起敲击才可触发,默认1根@property (nonatomic) NSUInteger numberOfTouchesRequired __TVOS_PROHIBITED;

2. UIPinchGestureRecognizer(捏合,用于缩放)

提示: 模拟器快捷键:opsin + shift 向上拖“两个触摸点”

    // 缩放比例@property (nonatomic) CGFloat scale;
    // 缩放速度@property (nonatomic,readonly) CGFloat velocity;

3. UIPanGestureRecognizer(拖拽)

    // 拖动的最短距离@property (nonatomic) NSUInteger minimumNumberOfTouches __TVOS_PROHIBITED;
    // 拖动的最长距离@property (nonatomic) NSUInteger maximumNumberOfTouches __TVOS_PROHIBITED;
    // 在指定的view上得坐标- (CGPoint)translationInView:(nullable UIView *)view;
    // 设置在view中移动以后的坐标为translation- (void)setTranslation:(CGPoint)translation inView:(nullable UIView *)view;
    // 拖动view,返回的值就用于计算view相对于父控件拖动的速度- (CGPoint)velocityInView:(nullable UIView *)view;

4. UISwipeGestureRecognizer(轻扫)

    // 需要几根手指一起轻扫才可触发,默认1根@property(nonatomic) NSUInteger numberOfTouchesRequired __TVOS_PROHIBITED;
    // 设置轻扫方向@property(nonatomic) UISwipeGestureRecognizerDirection direction;

5. UIRotationGestureRecognizer(旋转)

    // 旋转角度@property (nonatomic) CGFloat rotation;
    // 旋转速度@property (nonatomic,readonly) CGFloat velocity;

6. UILongPressGestureRecognizer(长按)

注意: 长安手势一般会触发两次,所有一般为了只做一次,要做一次判断

    // 需要连续长按几次才可触发,默认0次@property (nonatomic) NSUInteger numberOfTapsRequired;
    // 需要几根手指一起长按才可触发,默认1根@property (nonatomic) NSUInteger numberOfTouchesRequired __TVOS_PROHIBITED;
    // 最小长按时间@property (nonatomic) CFTimeInterval minimumPressDuration;
    // 允许移动距离@property (nonatomic) CGFloat allowableMovement;

六. 手势的具体使用

    #import "ViewController.h"@interface ViewController () @property (weak, nonatomic) IBOutlet UIImageView *imageView;
    @end@implementation ViewController- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib. [self setUpTap];
    [self setUpLongPress];
    [self setUpSwipe];
    [self setUpRotation];
    [self setUpPinch];
    [self setUpPan];
    }
    #pragma mark - 点按手势- (void)setUpTap {
    UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(actionUpTap)];
    // 多个手势必须要代理 gestureRecognizer.delegate = self;
    [_imageView addGestureRecognizer:gestureRecognizer];
    }
    - (void)actionUpTap {
    NSLog(@"点按手势");
    }
    #pragma mark - 长按手势- (void)setUpLongPress {
    UILongPressGestureRecognizer *gestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(actionLongPress)];
    gestureRecognizer.delegate = self;
    [_imageView addGestureRecognizer:gestureRecognizer];
    }
    - (void)actionLongPress {
    NSLog(@"长按手势");
    }
    #pragma mark - 轻扫手势- (void)setUpSwipe{
    // 默认向右轻扫,如果要同时有多个轻扫方向,必须要创建轻扫对象 UISwipeGestureRecognizer *gestureRecognizerRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(actionSwipe)];
    [_imageView addGestureRecognizer:gestureRecognizerRight];
    UISwipeGestureRecognizer *gestureRecognizerLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(actionSwipe)];
    // 向左轻扫 gestureRecognizerLeft.direction = UISwipeGestureRecognizerDirectionLeft;
    [_imageView addGestureRecognizer:gestureRecognizerLeft];
    UISwipeGestureRecognizer *gestureRecognizerUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(actionSwipe)];
    // 向上轻扫 gestureRecognizerUp.direction = UISwipeGestureRecognizerDirectionUp;
    [_imageView addGestureRecognizer:gestureRecognizerUp];
    UISwipeGestureRecognizer *gestureRecognizerDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(actionSwipe)];
    // 向下轻扫 gestureRecognizerDown.direction = UISwipeGestureRecognizerDirectionDown;
    [_imageView addGestureRecognizer:gestureRecognizerDown];
    }
    - (void)actionSwipe {
    NSLog(@"轻扫手势");
    }
    #pragma mark - 旋转手势- (void)setUpRotation {
    UIRotationGestureRecognizer *gestureRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(actionRotation:)];
    gestureRecognizer.delegate = self;
    [_imageView addGestureRecognizer:gestureRecognizer];
    }
    - (void)actionRotation:(UIRotationGestureRecognizer *)rotation {
    _imageView.transform = CGAffineTransformRotate(_imageView.transform, rotation.rotation);
    // 复位 rotation.rotation = 0;
    }
    #pragma mark - 捏合手势- (void) setUpPinch {
    UIPinchGestureRecognizer *gestureRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(actionPinch:)];
    gestureRecognizer.delegate = self;
    [_imageView addGestureRecognizer:gestureRecognizer];
    }
    - (void)actionPinch:(UIPinchGestureRecognizer *)pinch {
    _imageView.transform = CGAffineTransformScale(_imageView.transform, pinch.scale, pinch.scale);
    // 复位 pinch.scale = 1;
    }
    #pragma mark - 拖拽手势- (void)setUpPan {
    UIPanGestureRecognizer *gestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(actionPan:)];
    gestureRecognizer.delegate = self;
    [_imageView addGestureRecognizer:gestureRecognizer];
    }
    - (void)actionPan:(UIPanGestureRecognizer *)pan {
    //NSLog(@"%ld",[pan numberOfTouches]);
    // 获取手势的触摸点 // CGPoint curP = [pan locationInView:self.imageView];
    CGPoint panTrans = [pan translationInView:_imageView];
    _imageView.transform = CGAffineTransformTranslate(_imageView.transform, panTrans.x, panTrans.y);
    // 复位 [pan setTranslation:CGPointZero inView:_imageView];
    }
    #pragma mark - 手势代理// 是否允许多个同时支持多个手势,默认不允许,手势必须要设置代理- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
    }
    // 是否允许触发手势事件- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    return YES;
    }
    // 是否允许接收触摸点- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    return YES;
    }
    @end
相关热词搜索: