六大操作手势
2016-10-31 本文已影响148人
DDY
使用 touches 方法来监听 view 的触摸事件弊端:
- 必须得自定义 view, 在自定义的 View 当中去实现 touches 方法
- 由于是在 view 内部的 touches 方法中监听触摸事件,因此默认无法让其外界对象监听该 view 的触摸事件
- 不容易区分用户具体的手势行为
鉴于这些问题,在iOS 3.2 之后,苹果推出了手势识别功能(Gesture Recognizer)
- 利用 UIGestureRecognizer,能轻松识别用户在某个 view 上面做的一些常见手势
- UIGestureRecognizer 是一个抽象类,定义了所有手势的基本行为,使用它的子类才能处理具体的手势
- 点按手势 UITapGestureRecognizer
- 长按手势 UILongPressGestureRecognizer
- 拖拽手势 UIPanGestureRecognizer
- 轻扫手势 UISwipeGestureRecognizer
- 旋转手势 UIRotationGestureRecognizer
- 捏合手势 UIPinchGestureRecognizer
手势的使用方法
- 创建手势
- 添加手势
- 实现手势方法
- 补充(手势也可以设置代理)
代码示范
点按手势 UITapGestureRecognizer
- (void)topGes {
UITapGestureRecognizer *tapGes = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap)];
tapGes.delegate = self;
[self.imageView addGestureRecognizer:tapGes];
}
- (void)tap {
NSLog(@"现在是点按手势");
}
// 代理方法:是否允许接收手指
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
//让图片左边可以点击,右边不能点击
CGPoint curP = [touch locationInView:self.imageView];
if (curP.x > self.imageView.bounds.size.width * 0.5) {
return NO;
}else {
return YES;
}
}
长按手势 UILongPressGestureRecognizer
- (void)longPGes {
UILongPressGestureRecognizer *longPGes = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longP:)];
[self.imageView addGestureRecognizer:longPGes];
}
//当长按并移动时,会多次调用这个方法
- (void)longP:(UILongPressGestureRecognizer *)longP {
//判断长按时的状态
if (longP.state == UIGestureRecognizerStateBegan) {
NSLog(@"开始长按");
}else if (longP.state == UIGestureRecognizerStateChanged) {
NSLog(@"- - - 长按时手指移动了 - - -");
}else if (longP.state == UIGestureRecognizerStateEnded) {
NSLog(@"长按结束");
}
}
拖拽手势 UIPanGestureRecognizer
- (void)panGes {
UIPanGestureRecognizer *panGes = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
[self.imageView addGestureRecognizer:panGes];
}
- (void)pan:(UIPanGestureRecognizer *)pan {
//获取偏移量
CGPoint transP = [pan translationInView:self.imageView];
NSLog(@"transP = %@", NSStringFromCGPoint(transP));
//移动图片
self.imageView.transform = CGAffineTransformTranslate(self.imageView.transform, transP.x, transP.y);
//清零,不要累加
[pan setTranslation:CGPointZero inView:self.imageView];
}
轻扫手势 UISwipeGestureRecognizer
- 一个手势只能对应一个方向,若要支持多个方向,可以添加多个手势
- 轻扫手势的方向默认是向右
- 可以通过修改手势的 direction 属性修改手势的方向
- (void)swipeGes {
//一个手势只能对应一个方向,若要支持多个方向,可以添加多个手势
UISwipeGestureRecognizer *swipeGes1 = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)];
//轻扫手势的方向默认是向右
[self.imageView addGestureRecognizer:swipeGes1];
UISwipeGestureRecognizer *swipeGes2 = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)];
//可以修改手势的方向,向上
swipeGes2.direction = UISwipeGestureRecognizerDirectionUp;
[self.imageView addGestureRecognizer:swipeGes2];
UISwipeGestureRecognizer *swipeGes3 = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)];
//手势的方向,向左
swipeGes3.direction = UISwipeGestureRecognizerDirectionLeft;
[self.imageView addGestureRecognizer:swipeGes3];
UISwipeGestureRecognizer *swipeGes4 = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)];
//手势的方向,向下
swipeGes4.direction = UISwipeGestureRecognizerDirectionDown;
[self.imageView addGestureRecognizer:swipeGes4];
}
- (void)swipe:(UISwipeGestureRecognizer *)swipe {
if (swipe.direction == UISwipeGestureRecognizerDirectionLeft) {
NSLog(@"向左轻扫 --- left");
}else if (swipe.direction == UISwipeGestureRecognizerDirectionRight){
NSLog(@"向右轻扫 --- right");
}else if (swipe.direction == UISwipeGestureRecognizerDirectionUp){
NSLog(@"向上轻扫 --- up");
} else if (swipe.direction == UISwipeGestureRecognizerDirectionDown) {
NSLog(@"向下轻扫 --- down");
}
}
旋转手势 UIRotationGestureRecognizer
- (void)rotationGes {
UIRotationGestureRecognizer *rotationGes = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotation:)];
[self.imageView addGestureRecognizer:rotationGes];
}
- (void)rotation:(UIRotationGestureRecognizer *)rotationGes {
//获取旋转的度数
CGFloat angle = rotationGes.rotation;
//旋转图片
self.imageView.transform = CGAffineTransformRotate(self.imageView.transform, angle);
//清零
[rotationGes setRotation:0];
}
捏合手势 UIPinchGestureRecognizer
- (void)pinchGes {
UIPinchGestureRecognizer *pinchGes = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinch:)];
[self.imageView addGestureRecognizer:pinchGes];
}
- (void)pinch:(UIPinchGestureRecognizer *)pinchGes {
//获取缩放比例
CGFloat scale = pinchGes.scale;
NSLog(@"scale = %f", scale);
//缩放图片
self.imageView.transform = CGAffineTransformScale(self.imageView.transform, scale, scale);
//初始化大小
[pinchGes setScale:1];
}
手势的混合使用
- 默认情况下只能同时支持一种手势
- 若要同时支持多种手势,可以给要支持的手势设置代理,并实现以下代理方法
// 是否允许同时支持多个手势
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
手势冲突的解决
- 单机和双击区分
[singeTap requireGestureRecognizerToFail:doubleTap];
- UIPanGestureRecognizer和UITapGestureRecognizer冲突
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] && [otherGestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) {
return NO;
}
return YES;
}
- tableView添加手势,tableView父视图添加手势后区分
#pragma mark tapGestureRecgnizerdelegate 解决手势冲突
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if ([touch.view isKindOfClass:[UITableView class]]) {
return NO;
}
if ([NSStringFromClass([touch.view class]) isEqualToString:@"UITableViewCellContentView"]) {
return NO;
}
return YES;
}
- scrollview和tableview嵌套,区分滚动代理
#pragma mark - scrollView delegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if ([scrollView isKindOfClass:[UITableView class]]) {
NSLog(@"UITableView");
} else {
NSLog(@"UIScrollview");
}
}
- UIScrollView和子视图TableView的cell右滑冲突
继承UIScrollView的子类重写下面的方法即可
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
//NSLog(@"手势触发的类=%@",NSStringFromClass([touch.view class]));
// 若为UITableViewCellContentView(即点击了tableViewCell),则不截获Touch事件
if ([NSStringFromClass([touch.view class])isEqualToString:@"UITableViewCellContentView"]) {
return NO;
}return YES;
}
-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
// 若为UITableViewCellContentView(即点击了tableViewCell),则不截获Touch事件
if ([NSStringFromClass([gestureRecognizer.view class])isEqualToString:@"UITableViewCellContentView"]) {
return NO;
}
return YES;
}
附