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