3.5 iOS手势识别

2.1手势识别

(一)概述

如果需要在应用程快速而轻松的处理轻按,轻扫,捏合和旋转等触摸事件,该怎么办?
答案:直接实现自定义view的touches方法.
但是这种放方式有几个明显的缺点:
1>必须得自定义view(也就是说我们开发软件界面上凡是需处理触摸事件的组件都需要自定义).
2>由于是在view内部的touches方法中监听触摸事件,因此默认情况下,无法让其他外接对象监听view的触摸事件.
3>不容易区分用户具体的手势行为(轻扫,捏合,旋转等).
4>编写代码比较繁琐.

14636447151250.jpg

为了解决以上这些问题,苹果公司从iOS3.2开始引入了手势识别器(UIGestureRecognizer).
UIGestureRecognizer是一个抽象类,提供了处理手势的通用框架,使用它的子类才能出来具体的手势,苹果官方为我们提供了下面常用的一些手势:

1. UITapGestureRecognizer (敲击) 2. UIPinchGestureRecognizer (捏合,用于缩放) 3. UIRotationGestureRecognizer (旋转) 4. UISwipeGestureRecognizer (轻扫) 5. UIPanGestureRecognizer (拖拽) 6. UILongPressGestureRecognizer (长按)

手势识别器的类型
1.>离散型:离散型手势识别器用来处理快捷而简单的交互,如敲击.这种类型的手势识别器一旦识别就无法取消,而且只会调用一次手势操作事件(初始化手势时指定的回调方法). 2.>连续型:连续型手势识别器需要不断的获取有关手势的信息以更新UI,如捏合和旋转.

(二)使用手势识别的步骤:
1.创建手势.
2.设置手势的属性.(通常情况下不需要设置这些属性,只需要指定所属view以及要执行的方法即可)
3.添加手势到对应的view上.
4.监听手势的触发.

     // 1.创建手势
    UITapGestureRecognizer *tapG = [[UITapGestureRecognizer alloc] init];
    // 2.设置手势的属性
    tapG.numberOfTapsRequired = 2;//需要连续敲击两次
    tapG.numberOfTouchesRequired = 2;//需要两根手指一起敲击
    // 3.将手势添加到view上
    [chatView addGestureRecognizer:tapG];
    // 4.监听手势的触发
    [tapG addTarget:self action:@selector(tapGAction)];

(三)UIGestureRecognizer常用属性和方法和UIGestureRecognizerDelegate常用方法

1.>UIGestureRecognizer常用属性和方法

/*常用属性*/
// 手势的状态
@property(nonatomic,readonly) UIGestureRecognizerState state; 
// 设置手势的代理
@property(nullable,nonatomic,weak) id <UIGestureRecognizerDelegate> delegate; // the gesture recognizer's delegate
// 使手势可用默认为YES
@property(nonatomic, getter=isEnabled) BOOL enabled;
  
/*常用方法*/
// 初始一个手势并且添加手势的监听方法
- (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;

2.>UIGestureRecognizerDelegate常用方法

// 是否允许开始触发手势
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;
// 是否允许支持多个手势,默认是不支持多个手势的.返回YES表示支持多个手势
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
// 是否允许接收手势的触摸点,获取到当前触摸点可以允许手势作用view指定的区域,如:指定view宽度的一半可以使用手势(接收触摸点),一半不可以使用手势(接收触摸点)
- (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;
    }
}

(四)常用手势的使用
1>UITapGestureRecognizer(敲击)

#pragma mark - 点按手势
- (void)setUpTap
{
    // 创建点按手势
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)];
    // 将手势作用到对应的view上
    [_imageView addGestureRecognizer:tap];
}
// 监听手势的方法
- (void)tap:(UITapGestureRecognizer *)tap
{
    NSLog(@"%s",__func__);
}

2>UIPinchGestureRecognizer(捏合)

/*
注意:要在iOS模拟器中执行捏合手势,可以按住键盘Option键,将出现两个表示手指的圆圈,在移动鼠标
    表示手指的圆圈将相隔更近或更远.需要调整手指中心点位置可以同时按住键盘上的shift+option键
    并移动鼠标.
*/
#pragma mark - 捏合
- (void)setUpPinch
{
    // 创建捏合手势并且添加监听手势的方法
    UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinch:)];
    // pinch.delegate = self; // 设置手势的代理
    // 将手势作用到对应的view
    [self.imageView addGestureRecognizer:pinch];
}
// 监听手势的方法
- (void)pinch:(UIPinchGestureRecognizer *)pinch
{
// 可以通过捏合手势获取对应的角度来修改view的transform属性使view可以进行捏合
    self.imageView.transform = CGAffineTransformScale(self.imageView.transform, pinch.scale, pinch.scale);
    // 复位
    pinch.scale = 1;
}

3>UIRotationGestureRecognizer(旋转)

#pragma mark - 旋转
- (void)setUpRotation
{
     // 创建一个旋转手势并且添加一个监听方法
    UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotation:)];
    // 设置手势的代理
    rotation.delegate = self;
    // 将手势添加到对应的view
    [self.imageView addGestureRecognizer:rotation];
}

// 当旋转手势触发时调用该方法,默认传递的旋转的角度都是相对于最开始的位置
- (void)rotation:(UIRotationGestureRecognizer *)rotation
{
    // 通过旋转手势获取旋转的旋转角度修改view的transform属性使view可以进行旋转
    self.imageView.transform = CGAffineTransformRotate(self.imageView.transform, rotation.rotation);  
    // 复位
    rotation.rotation = 0; 
    // 获取手势旋转的角度
    // NSLog(@"%f",rotation.rotation);
}

4>UISwipeGestureRecognizer(轻扫)

#pragma mark - 轻扫
    /*轻扫手势支持的方法,默认为右*/
   UISwipeGestureRecognizerDirectionRight = 1 << 0, // 右
   UISwipeGestureRecognizerDirectionLeft  = 1 << 1, // 左
   UISwipeGestureRecognizerDirectionUp    = 1 << 2, // 上
   UISwipeGestureRecognizerDirectionDown            // 下

- (void)setUpSwipe
{
    // 创建一个轻扫手势并且添加监听的方法,默认轻扫的方向是往右
    UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe)];
    // 设置轻扫手势的方向向上
    swipe.direction = UISwipeGestureRecognizerDirectionUp;
    // 将手势添加到view上
    [self.imageView addGestureRecognizer:swipe];
    
    // 如果以后想要一个控件支持多个方向的轻扫,必须创建多个轻扫手势,一个轻扫手势只支持一个方向
    // 默认轻扫的方向是往右
    UISwipeGestureRecognizer *swipeDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe)];
    // 设置轻扫手势的方向向下
    swipeDown.direction = UISwipeGestureRecognizerDirectionDown;
    // 将手势添加到view上
    [self.imageView addGestureRecognizer:swipeDown];
}
// 当轻扫手势触发时调用该方法
- (void)swipe
{
    NSLog(@"%s",__func__);
}

5>UIPanGestureRecognizer(拖拽)

#pragma mark - 拖拽
- (void)setUpPan
{
    // 创建一个拖拽手势并且添加监听方法
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
    // 将拖拽手势添加到view上
    [self.imageView addGestureRecognizer:pan];
}
// 当拖拽手势触发时调用该方法
- (void)pan:(UIPanGestureRecognizer *)pan
{
    // 获取手势的触摸点
   // CGPoint curP = [pan locationInView:self.imageView];
    
    // 移动视图
    // 获取手势的移动,也是相对于最开始的位置
    CGPoint transP = [pan translationInView:self.imageView];
    // 修改view的transform属性
    self.imageView.transform = CGAffineTransformTranslate(self.imageView.transform, transP.x, transP.y);
    // 复位
    [pan setTranslation:CGPointZero inView:self.imageView];
  //  NSLog(@"%@",NSStringFromCGPoint(curP));
}

6>UILongPressGestureRecognizer(长按)

#pragma mark - 长按
// 默认会触发两次
- (void)setUpLongPress
{
      // 创建一个长按手势并且设置监听方法
    UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
    // 将长按手势添加到view上
    [self.imageView addGestureRecognizer:longPress];
}

// 当触发了长按手势时调用该方法
- (void)longPress:(UILongPressGestureRecognizer *)longPress
{       
     // 判断一下长按手势是否开始,如果开始可以监听
    if (longPress.state == UIGestureRecognizerStateBegan) {
        NSLog(@"%s",__func__);
    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容