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、代理办法。
属性
名称类型阐明默认值
stateUIGestureRecognizerState以后手势状态,可分为手势开始,手势扭转,手势完结等等
enabledBOOL是否启用YES
viewUIView手势监听的视图
requiresExclusiveTouchTypeBOOL是否疏忽其余手势类型,设置为YES将只响应一种手势类型NO
numberOfTouchesNSUInteger多少根手指触发手势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(@"产生向下滑动");}