iOS 开发中的常用手势事件简述

在开发过程中,我们为了提高用户体验和App的交互友好性,我们通常会在App中添加一些手势,来辅助用户操作.那么这篇文章将简述一下在开发过程中我们经常用到的手势事件.

管理手势事件的类是UIGestureRecognizer,这是一个手势识别器.而手势识别器则是一个特殊的触摸事件.手势事件是使用了target-action模式(目标-动作模式)设计的,所以我们在使用的时候指定目标跟动作就好了.

UIGestureRecognizer

UIGestureRecognizer是一个抽象的父类,在开发过程中我们一般不使用这个类,而是使用其子类.

UIGestureRecognizer的子类

上图展示了UIGestureRecognizer的子类.下面我们就来介绍其中常用的集中手势事件.

First

我们进行描述之前先假定一个场景,在UIViewController上有一个UIView,设置颜色为红色,我们取名为redView.现在我们对其进行手势添加.

场景

UIPanGestureRecognizer平移手势

现在UIView上面是没有任何可以被触发的事件的,现在我们添加一个平移手势,让这张图片可以在屏幕上任意平移.
此时我们会用到UIGestureRecognizer的子类UIPanGestureRecognizer,在API中有两个属性三个方法.其中属性使用来控制触摸到UIView 的触点个数.方法我们通过代码演示.
代码如下:

// 我们初始化这个手势事件,并为它制定一个触发方法,就是让他平移
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panView:)];
//我们将手势事件添加到view上
[_redView addGestureRecognizer:pan];

平移手势触发的方法为:

- (void)panView:(UIPanGestureRecognizer *)sender{
    CGPoint point = [sender translationInView:_redView];    
    // 以上次位置为标准
    sender.view.transform = CGAffineTransformTranslate(sender.view.transform, point.x, point.y);
    // 增量值为零
    [sender setTranslation:CGPointZero inView:sender.view];
}

我们为了能让这个View自由平移,我们设置为每次移动是以上一次的位置为标准,并且其增量值为零.

UIScreenEdgePanGestureRecognizer屏幕边缘平移手势

UIScreenEdgePanGestureRecognizer是UIPanGestureRecognizer的子类,比父类多了一个属性

UIScreenEdgePanGestureRecognizer

同样是上面的场景,如果我们在view上添加屏幕边缘手势,但是首先声明一下,由于是屏幕边缘移动,我们知道,屏幕四个边缘,上,左,下,右.所以我们在添加手势的时候必须先设置UIScreenEdgePanGestureRecognizer的edges这个属性.在这里我设置为滑动右侧边缘,视图移动.

edges这个属性

它是一个枚举变量,枚举元素表示出发这个事件需要的手势位置.

    UIScreenEdgePanGestureRecognizer *screenEdgePan = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:@selector(screenEdgePanView:)];
    // 属性设置(设置边界)
    // 注意,使用屏幕边缘平移,需要注意两点
    // 1.视图的位置
    // 2.设置edges属性
    screenEdgePan.edges = UIRectEdgeRight;
    [_redView addGestureRecognizer:screenEdgePan];

我们同样为它添加移动事件.

- (void)screenEdgePanView:(UIScreenEdgePanGestureRecognizer *)sender{
    // 计算偏移量
    CGPoint point = [sender translationInView:_redView];
    // 进行平移
    sender.view.transform = CGAffineTransformMakeTranslation(point.x, point.y);   
}

UITapGestureRecognizer轻拍事件

轻拍事件有两个属性,分别是设置轻拍时手指的个数和轻拍的次数.

UITapGestureRecognizer

我们依然使用上面的场景,为了演示效果,我们设置轻拍手指为两个,轻拍次数为两次.触发的事件是随机变换颜色.

    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapView:)];
    // 设置属性
    // 轻拍次数
    tap.numberOfTapsRequired = 2;
    // 手指个数
    tap.numberOfTouchesRequired = 2; 
    // 添加到视图上
    [_redView addGestureRecognizer:tap];

触发的事件为:

- (void)tapView:(UITapGestureRecognizer *)sender{   
    _redView.backgroundColor = [UIColor colorWithRed:arc4random()%256/255.0 green:arc4random()%256/255.0 blue:arc4random()%256/255.0 alpha:0.9];
}

UISwipeGestureRecognizer轻扫手势

轻扫手势有两个属性:
第一个是设置轻扫手指的个数,默认是一个.而第二个则是设置轻扫的方向.我们在view上面添加手势,手势触发的事件依然是让view的颜色随机改变.

    UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeView:)];
    swipe.numberOfTouchesRequired = 1;
    // 设置轻扫方向
//    swipe.direction = UISwipeGestureRecognizerDirectionUp;
    swipe.direction = UISwipeGestureRecognizerDirectionDown;
//    swipe.direction = UISwipeGestureRecognizerDirectionLeft;
//    swipe.direction = UISwipeGestureRecognizerDirectionRight;
    [_redView addGestureRecognizer:swipe];

触发的事件为:

- (void)swipeView:(UISwipeGestureRecognizer *)sender{
    _redView.backgroundColor = [UIColor colorWithRed:arc4random()%256/255.0 green:arc4random()%256/255.0 blue:arc4random()%256/255.0 alpha:0.9]; 
}

UILongPressGestureRecognizer长按手势

对于长按手势我们设置的场景依然跟上面一样.

UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressView:)];
    // 最小长按时间
longPress.minimumPressDuration = 2;
[_redView addGestureRecognizer:longPress];

在上面的代码中,我们通过长按手势的minimumPressDuration属性来设置最小长按时间,也就是设置了事件longPressView:被触发所需要长按的最小时间.

对于长按手势,我们设置的事件依旧是随机改变颜色

- (void)longPressView:(UILongPressGestureRecognizer *)sender{
    // 判断手势状态
    if (sender.state == UIGestureRecognizerStateEnded) {
         NSLog(@"长按状态!");
        _redView.backgroundColor = [UIColor colorWithRed:arc4random()%256/255.0 green:arc4random()%256/255.0 blue:arc4random()%256/255.0 alpha:0.9];
    } 
}

在上面的代码中我们通过state来判断手势的状态,这个属性是其父类的属性,这个属性中包含了手势事件从开始到结束的整个状态.读者可以自行参考苹果官方API,在此就不赘述.以上就是长按手势.

UIPinchGestureRecognizer捏合手势

我们都知道当我们查看相册中照片的时候,我们会通过手指的捏合或扩展来进行照片的缩小或放大.我们利用上面的场景对,view进行添加捏合手势实现类似的功能.

在此,我们可以按住键盘的Alt键加上鼠标来实现这个场景的模拟.

UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchView:)];
    
// 添加手势
[_redView addGestureRecognizer:pinch];

相信通过上面的手势,我们在这个地方已经不需要描述事件的触发了

- (void)pinchView:(UIPinchGestureRecognizer *)sender{
    // 以上一次的为标准
    sender.view.transform = CGAffineTransformScale(sender.view.transform, sender.scale, sender.scale);
    // 重新设置缩放比例(1是正常缩放, <1 是缩小, >1是放大 )
    sender.scale = 1;    
}

在这里我们使用了仿射变换来控制view放大缩小的比例.

UIRotationGestureRecognizer旋转手势

如同上面一样我们使用同样的方法来创建手势,并添加到视图上.

UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotationView:)];
    
[_redView addGestureRecognizer:rotation];

我们依旧使用2D仿射变换来实现View的旋转

- (void)rotationView:(UIRotationGestureRecognizer *)sender{
    
    // 两个参数,以上一次的位置为标准
    sender.view.transform = CGAffineTransformRotate(sender.view.transform, sender.rotation);
    // 清除增量
    sender.rotation = 0.0;
   
}

其他

在UIView中有一个gestureRecognizers属性,它表征了View上面的手势类型,我们可以通过这个属性来遍历查看View上面添加的手势.

for (UIGestureRecognizer *ges in _redView.gestureRecognizers) {
        NSLog(@"%@",ges);
    }

总结

以上我们介绍了几种简单的手势.在开发过程中,我们可以通过添加手势来提高用户体验,增加App对用户的友好性.相信通过上面的几种手势,我们队iOS开发中的手势也有了大致的了解,如果您在阅读过程中发现疑问或者疏漏,欢迎留言探讨或更正,我将不胜感激.

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

推荐阅读更多精彩内容