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(@"产生向下滑动");}