乐趣区

关于ios:IOS-定义手势监听器详解利用-UIGestureRecognizer-进行捏合旋转平移点击长按手势事件响应

IOS 中咱们能够通过 UITouch 进行触摸事件监听,然而 UITouch 实现捏合、旋转、长按等手势事件监听十分麻烦。IOS 中提供 UIGestureRecognizer 的子类帮咱们简洁等实现捏合、旋转等非凡手势监听。并且一个视图可增加多个不同等手势监听器。

开启 userInteractionEnabled

IOS 中 UIView 默认是不可响应事件的,咱们须要开启 userInteractionEnabled 方可进行事件响应。上面代码中咱们创立了一个图片视图,并且开始事件响应。UIView 通过 addGestureRecognizer 进行增加手势监听器和 removeGestureRecognizer 删除手势监听器

// 创立图片视图
- (void) creareImg {UIImage* image = [UIImage imageNamed:@"zz.jpeg"];
    _imageView = [[UIImageView alloc] initWithImage:image];
    UIScreen* screen = [UIScreen mainScreen];
    const int width = 200;
    const int height = 100;
    const float x = screen.bounds.size.width / 2 - width / 2;
    const float y = screen.bounds.size.height / 2 - height;
    _imageView.frame = CGRectMake(x, y, width, height);
    _imageView.userInteractionEnabled = YES;
    [self.view addSubview:_imageView];
}

理解 UIGestrueRecognizer

在开始应用自定义手势之前咱们先理解一下 UIGestrueRecognizer 的,因为自定义都是基于 UIGestrueRecognizer 继承实现的。UIGestrueRecognizer 是一个手势监听器,它能够设置多个手指同时触发触发事件等行为。它具备代理协定 UIGestureRecognizerDelegate 上面我来看一下它次要的属性和 API、代理办法。

属性
名称 类型 阐明 默认值
state UIGestureRecognizerState 以后手势状态,可分为手势开始,手势扭转,手势完结等等
enabled BOOL 是否启用 YES
view UIView 手势监听的视图
requiresExclusiveTouchType BOOL 是否疏忽其余手势类型,设置为 YES 将只响应一种手势类型 NO
numberOfTouches NSUInteger 多少根手指触发手势 1
API
  • - (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 删除事件监听函数
  • - (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer 增加其余手势抵触生效器,当触发以后手势时,指定的手势将生效。
  • - (CGPoint)locationInView:(nullable UIView*)view 获取绝对于指定视图的坐标地位
  • - (CGPoint)locationOfTouch:(NSUInteger)touchIndex inView:(nullable UIView*)view 获取指定手指绝对指定视图的坐标地位
代理协定
  • - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer 手势筹备开启时候触发,返回 NO 则勾销手势。
  • - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer 当手势与其余手势同时产生辨认时候触发,返回 YES 运行两个手势同时进行,返回 NO 则阻止同时辨认。
  • - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch 是否给事件接管手指。在手势开始触发事件触发前触发,返回 NO 能够阻止事件获取触摸的手指。
  • - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceivePress:(UIPress *)press 是否给按下事件接管手指,在按下手势事件触发前触发。返回 NO 可阻止事件获取触摸的手指。
咱们理解革除 GestureRecognizer 类,上面咱们来理解其子类手势的应用。

UITapGestureRecognizer 点击手势

点击手势,可设置手指数量、点击次数触发的手势

// 创立点击手势
- (void) createTapGes {
    _imageView.userInteractionEnabled = YES; // 开启响应事件属性
    UITapGestureRecognizer* tapOneGes = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(big)]; // 创立手势
    tapOneGes.numberOfTapsRequired = 1; // 触发事件的点击次数
    tapOneGes.numberOfTouchesRequired = 1; // 触发事件的手指数量
    [_imageView addGestureRecognizer:tapOneGes]; // 增加手势监听器
}
// 点击触发事件
- (void) big {UIScreen* screen = [UIScreen mainScreen];
    [UIView beginAnimations:nil context:nil]; // 开始布局动画
    _imageView.frame = CGRectMake(0, 0, screen.bounds.size.width, screen.bounds.size.height);
    [UIView commitAnimations]; // 完结布局动画
}

UIPinchGestureRecognizer 捏合手势

捏合手势,示意双指捏合缩放的手势触发。罕用于对图片查看缩放事件监听

// 捏合手势
- (void) createPinchGes {UIPinchGestureRecognizer* pinch = [[UIPinchGestureRecognizer alloc] init]; // 创立手势
    [pinch addTarget:self action:@selector(scale:)]; // 增加事件函数
    pinch.delegate = self; // 设置代理
    [_imageView addGestureRecognizer:pinch]; // 视图增加手势监听器
}

- (void) scale: (UIPinchGestureRecognizer*) pinch {
    UIView* IView = pinch.view; // 获取监听的视图
    CGAffineTransform transiform = CGAffineTransformScale(IView.transform, pinch.scale, pinch.scale); // 计算缩放后的矩阵
    if (transiform.a < 0.4) { // 缩放小于 0.4 阻止
        transiform.a = 0.4;
        transiform.d = 0.4;
    }
    IView.transform = transiform; // 从新设置矩阵
    pinch.scale = 1; // 重置缩放矩阵,否则手势会始终累加
}

// 增加容许多个手势触发代理函数
- (BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {return  YES;}

下面代码中咱们通过获取捏合手势的 scale 属性获取用户捏合缩放的大小。并且应用内置 api CGAffineTransformScale 从新计算了视图的 2D 矩阵(矩阵示意图像变形,能够理解一下图形学),留神!最初一步中必须重置手势的scale 否则会始终累加导致计算矩阵谬误,如果不想重置的话那就须要批改 CGAffineTransformScale 的第一个参数为根底矩阵参数。

UIRotationGestureRecognizer 旋转手势

旋转手势,可获取用户手指旋转的角度。

// 旋转手势
- (void) createRotateGes {UIRotationGestureRecognizer* rotate = [[UIRotationGestureRecognizer alloc] init];
    [rotate addTarget:self action:@selector(rotate:)];
    rotate.delegate = self;
    [_imageView addGestureRecognizer:rotate];
}
// 旋转触发事件
- (void) rotate: (UIRotationGestureRecognizer*) rotate {
    UIView* IView = rotate.view;
    IView.transform =  CGAffineTransformRotate(IView.transform, rotate.rotation); // 从新计算视图矩阵
    rotate.rotation = 0;
}

UIPanGestureRecognizer 平移手势

平挪动手势,比较简单就是手指挪动时候触发,然而提供平移的地位和平移的速度

// 平移手势
- (void) createPanGes {UIPanGestureRecognizer* pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
    pan.delegate = self;
    [_imageView addGestureRecognizer:pan];
}
- (void) pan: (UIPanGestureRecognizer*)pan {CGPoint speed = [pan velocityInView:_imageView]; // 获取挪动速度
    NSLog(@"x 速度 = %f, y 速度 = %f", speed.x, speed.y);
    CGPoint translation = [pan translationInView:_imageView]; // 获取挪动矩阵
    CGAffineTransform transform = CGAffineTransformTranslate(_imageView.transform, translation.x, translation.y);
    _imageView.transform = transform;
}

UILongPressGestureRecognizer 长按手势

长按对应视图触发手势,可设置手指数量和手指长按工夫

// 长按手势
- (void) createLongPassGes {UILongPressGestureRecognizer* longPass = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(pass:)];
    longPass.minimumPressDuration = 1; // 设置长按触发工夫,默认 0.5
    [_imageView addGestureRecognizer: longPass];
}

- (void)pass: (UILongPressGestureRecognizer*) longPass {if (longPass.state == UIGestureRecognizerStateBegan) {NSLog(@"开始长按");
    } else if (longPass.state == UIGestureRecognizerStateEnded) {NSLog(@"完结长按");
    } else if (longPass.state == UIGestureRecognizerStateChanged) {NSLog(@"长按产生扭转");
    }
}

UISwipeGestureRecognizer 轻滑手势

轻滑手势,相似咱们的平移手势。然而轻滑不同的是在用户疾速滑动时候速度,并且只提供滑动方向。

// 创立轻滑手势
- (void) createSwipe {UISwipeGestureRecognizer* swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swiper:)];
    swipe.direction = UISwipeGestureRecognizerDirectionDown;
    [_imageView addGestureRecognizer: swipe];
    swipe.delegate = self;
}

- (void) swiper: (UISwipeGestureRecognizer*)swiper {NSLog(@"产生向下滑动");
}
退出移动版