手势识别

  • 之前监听触摸事件的做法
    • 自定义一个view
    • 实现view的touches...方法,在方法内部实现具体处理代码
  • 通过touches...方法监听view触摸事件,有很明显的几个缺点
    • 必须得自定义view
    • 由于是在view内部的touches...方法中监听触摸事件,因此默认情况下,无法让其他外界对象监听view内部的触摸事件
    • 无法区分用户的具体手势行为
  • iOS 3.2之后,苹果推出了手势识别功能(Gesture Recognizer),在触摸事件处理方面,大大简化了开发者的开发难度
  • UIGestureRecognizer是一个抽象类,定义了所有手势的基本行为,使用它的子类才能处理具体的手势
  • 常见手势

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

// 创建手势识别器对象
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapIconView:)];
// 连续敲击2次
tap.numberOfTapsRequired = 2;
// 需要2根手指一起敲击
tap.numberOfTouchesRequired = 2;
// 添加手势识别器到对应的view上,那么就可以在此view上应用对应的手势
[self.iconView addGestureRecognizer:tap];
  • 通过手势状态可以在不同状态时做对应事情

    • UIGestureRecognizerStatePossible
      • 没有触摸事件发生,所有手势识别的默认状态
    • UIGestureRecognizerStateBegan
      • 一个手势已经开始但尚未改变或者完成时
    • UIGestureRecognizerStateChanged
      • 手势状态改变
    • UIGestureRecognizerStateEnded
      • 手势完成
    • UIGestureRecognizerStateCancelled
      • 手势取消,恢复至Possible状态
    • UIGestureRecognizerStateFailed
      • 手势失败,恢复至Possible状态
    • UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded
  • 同时支持多个手势是通过代理完成

    • 要同时支持的每个手势都必须设置代理
    • 实现UIGestureRecognizerDelegate协议
// 每个手势设置代理

// 是否允许同时支持多个手势,默认是不支持多个手势
// 返回YES表示支持多个手势
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}
  • 要一个控件支持多个方向的轻扫手势,必须创建多个轻扫手势,一个轻扫手势只支持一个方向(设置左右方向是能同时支持的,同时设置上下方向也是支持的)
  • 需要复位的手势
    • 旋转手势
    • 缩放手势
    • 拖拽手势
#pragma mark - 旋转手势
- (void)setupRotation
{
    UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotation:)];
    // 设置代理
    rotation.delegate = self;
    [self.imageView addGestureRecognizer:rotation];
}

// 默认传递的旋转的角度都是相对于最开始的位置
- (void)rotation:(UIRotationGestureRecognizer *)rotation
{
    self.imageView.transform = CGAffineTransformRotate(self.imageView.transform, rotation.rotation);

    // 复位,不然就会在原来的角度上累加,导致旋转的很快
    // 比如,第一次旋转了10°,第二次旋转的3°,实际却旋转了13°
    rotation.rotation = 0;
}

#pragma mark - 捏合
- (void)setupPinch
{
    UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinch:)];
    // 设置代理
    pinch.delegate = self;
    [self.imageView addGestureRecognizer:pinch];
}

- (void)pinch:(UIPinchGestureRecognizer *)pinch
{
    self.imageView.transform = CGAffineTransformScale(self.imageView.transform, pinch.scale, pinch.scale);

    // 复位,不然就会在原来的缩放比例上继续累加,导致缩放的很快
    // 比如,第一次缩小到0.8,如果不复位,第二次也缩小0.8,实际缩小了0.64
    pinch.scale = 1;
}

#pragma mark - 拖拽
- (void)setupPan
{
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
    // 设置代理
    pan.delegate = self;
    [self.imageView addGestureRecognizer:pan];
}

- (void)pan:(UIPanGestureRecognizer *)pan
{
    // 移动视图
    // 获取手势的移动,也是相对于最开始的位置
    CGPoint transP = [pan translationInView:self.imageView];

    self.imageView.transform = CGAffineTransformTranslate(self.imageView.transform, transP.x, transP.y);

    // 复位,如果不复位就会在原来的平移基础上累加,导致平移过快
    // 比如:第一次移动的10个点,如果不复位,第二次移动了5个点,实际上却移动了15个点
    [pan setTranslation:CGPointZero inView:self.imageView];
}

results matching ""

    No results matching ""