iOS学习笔记——触控与手势
触控
此部分内容已学良久,恨记之甚晚,忙矣,懒矣!本文简而记焉,恐日后忘也。
在iOS的触控事件中,有触控、事件以及响应者这三个角色,一个触摸则代表了一只手指和屏幕接触这个动作所包含的信息;而事件则包含了若干只手指在整个屏幕触控中整个过程的所有触摸信息,在C#的角度来说很容易会让人误以为是一种方法(或者叫函数)的指针;实际却不然,在这里无论触控和事件都是用于一些存储信息。而响应者则是确确实实的可以对真正的触控事件作相应处理;这三个角色在OC中分别对应着UITouch,UIEvent和UIResponder这三个类。而UIResponder实际上是所有响应者的基类,它定义了常见的响应者的一些编程接口。UIApplication、UIView都继承了UIResponder类,那么凡是继承UIView的类都继承了UIResponder,换句话说说有UIKit里面的控件都能响应手指对屏幕的触控事件。
在iOS的事件冒泡和在Android中的原理大致一样,但顺序则相反,每当手指接触到屏幕,最先对时间作出相应的是最顶层的视图控件,也就是整棵可视化树里面的叶子节点,然后按着可视化树的一直上溯,,一路上寻找是否有对象处理了这个事件,处理完毕了就停止往上溯,最后到达UIWindow和UIApplication,假如到了UIApplication还是没办法处理这个事件的话app就会认为它不具备处理这个事件的能力,然后把这个事件抛弃。
下面实际说一下实际的事件,按照触控的不同阶段,iOS分了三个事件来处理三种不同的触控阶段
touchesBegan:withEvent:当一只或多只手指触碰屏幕时触发
touchesMoved:withEvent:一只或多只手指在屏幕上移动时
touchesEnded:withEvent:一只活多只手指离开屏幕时
另外还有一个比较特殊的触控事件是手指触控的任一阶段在被系统事件取消时触发 touchesCancelled:withEvent:
下面这个例子则是通过手指在屏幕上的位置显示在左上角的Label中

把storyboard中的控件在ViewController里面建立关联属性
@interface HGNaviView1Controller () @property (weak, nonatomic) IBOutlet UILabel *lbStart; @property (weak, nonatomic) IBOutlet UILabel *lbMove; @property (weak, nonatomic) IBOutlet UILabel *lbUp; @end
然后加上下面四个方法,第一个方法TouchLog是用于输出日志信息,日志的内容是当前这个触控是有多少个触控点,和当前触控的阶段,UITouch的属性phase表示的是阶段,它是一个枚举UITouchPhase,枚举值如下
- UITouchPhaseBegan, 手指触摸屏幕
- UITouchPhaseMoved, 手指在屏幕上移动。
- UITouchPhaseStationary, 手指正在触摸的表面,但由于以前的事件没有发生移动。
- UITouchPhaseEnded, 手指从屏幕上离开。
- UITouchPhaseCancelled, 取消跟踪触摸,因为当(例如)用户将设备到他或她的脸
-(void)TouchLog:(UITouch *)touch
{
NSLog(@"Touch tapCount %d",touch.tapCount);
NSLog(@"Touch phase %d",touch.phase);
}
接下来的几个方法就是上面介绍到的触控事件的方法,三个方法的内容大致一样,都是从UIEvent里面获取到当前这个事件中所有触控点UITouch,通过遍历的形式调用上面定义的输出触控点信息的方法TouchLog,然后分别把手指最初接触屏幕时的坐标,移动过程中当前的坐标,还有提起手指时的坐标分别输出到视图界面的三个Label中
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
for(UITouch *t in event.allTouches)
{
[self TouchLog:t];
}
if(touches.count>)return;
UITouch *touch=[[event.allTouches allObjects]objectAtIndex:];
CGPoint locInsSelf=[touch locationInView:self.view];
self.lbStart.text=[[NSString alloc]initWithFormat:@"开始点击的位置是:(%2.3f,%2.3f)",locInsSelf.x, locInsSelf.y ] ;
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
for (UITouch *t in event.allTouches)
{
[self TouchLog:t];
}
if(touches.count>)return;
CGPoint locInsSelf=[[[event.allTouches allObjects]objectAtIndex:] locationInView:self.view];
self.lbMove.text=[[NSString alloc]initWithFormat:@"移动的位置是:(%2.3f,%2.3f)",locInsSelf.x, locInsSelf.y ] ;
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
for (UITouch *t in event.allTouches) {
[self TouchLog:t];
}
if(touches.count>)return;
CGPoint locInsSelf=[[[event.allTouches allObjects]objectAtIndex:] locationInView:self.view];
self.lbUp.text=[[NSString alloc]initWithFormat:@"抬起手指的位置是:(%2.3f,%2.3f)",locInsSelf.x, locInsSelf.y ] ;
}
输出的日志和界面如下面两幅图所示


手势
上面说的触控对于手指接触屏幕触发事件是最基本的,对于触屏手机而言一些固定的手势动作已经赋予了一定的含义,而这些手势是可以用过触控事件来实现,但是iOS也给出了比较简便的实现方式,其实就是手势UIGestureRecognizer,不过它只是一个抽象类,要实现某个具体的手势操作,还得用上它的子类才行,那下面先来介绍一下对于iOS而言有哪些手势
1.点击(Tap)
用于按下或选择一个控件或条目(类似于鼠标的Click动作)、
2.拖动(Drag)
拖动用于实现一些页面的滚动,以及对控件的移动功能。
3.滑动(Flick)
滑动用于实现页面的快速滚动和翻页的功能。
4.横扫(Swipe)
横扫手势用于激活列表项的快捷操作菜单
5.双击(Double Tap)
类似于鼠标的双击动作,通常用于放大并居中显示图片,或恢复原大小(如果当前已经放大)。同时,双击能够激活针对文字编辑菜单。
6.放大(Pinch open)
放大手势可以实现以下功能:打开订阅源,打开文章的详情。放大当前查看的图片或者文字内容。
7.缩小(Pinch close)
缩小手势,可以实现与放大手势相反且对应的功能的功能:关闭订阅源退出到首页,关闭文章退出至索引页。缩小当前查看的图片或者文字内容。
8.长按(Touch &Hold)
在我的订阅页,长按订阅源将自动进入编辑模式,同时选中手指当前按下的订阅源。这时可直接拖动订阅源移动位置。
针对文字长按,将出现放大镜辅助功能。松开后,则出现编辑菜单。
针对图片长按,将出现编辑菜单。
9.摇晃(Shake)
摇晃手势,将出现撤销与重做菜单。主要是针对用户文本输入的。
对于以上9种手势,iOS经过整合通过一下六个类来实现
- UITapGestureRecognizer
- UIPinchGestureRecognizer
- UIRotationGestureRecognizer
- UISwipeGestureRecognizer
- UIPanGestureRecognizer
- UILongPressGestureRecognizer
他们就分别代表了Tap(点击,有单击双击)、Pinch(捏合,有缩小有放大)、Rotation(旋转)、Swipe(滑动,快速移动,是用于监测滑动的方向的)、Pan (拖移,慢速移动,是用于监测偏移的量的)以及 LongPress(长按)
在使用这些手势的时候,需要在ViewController实现他们对应的delegate
@interface HGNaviView2Controller : UIViewController<UIGestureRecognizerDelegate>
{
}
@end
在viewDidLoad中添加以下代码
UITapGestureRecognizer *tap=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(SimpleTab:)]; tap.numberOfTouchesRequired=; [self.view addGestureRecognizer:tap]; UIPinchGestureRecognizer *pin=[[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(SimplePinch:)]; [self.view addGestureRecognizer:pin];
对应地要定义相应是方法,分别都是在手势触发的时候输出Log
-(void)SimpleTab:(UITapGestureRecognizer *)recognizer
{
NSLog(@"NumberOfTouches %d", recognizer.numberOfTouches);
}
-(void)SimplePinch:(UIPinchGestureRecognizer*)recognizer
{
NSLog(@"Pinch %f",recognizer.scale);
CGPoint location=[recognizer locationInView:self.view];
}
在屏幕上用两只手指点击屏幕就会输出以下内容

在屏幕上进行放大缩小的手势时就会输出以下内容

在实际中往往会出现这么一个情况,一个按钮同时存在着双击和单击操作,单击的时候会触发单击的,双击的时候就只会触发双击的,那这样子就添加两个UITapGestureRecognizer,单击的就把numberOfTapsRequired属性设成1,双击的时候就把numberOfTapsRequired设成2,结果运行的时候发现,单击的能正常单击,双击的时候,既触发了双击的,也触发了单击的。这样子不允许的,手势识别的应该是互斥的,解决这种情况就需要调用[A requireGestureRecognizerToFail:B]方法。代码就修改成如下,点击的时候就要么触发单击的,要么就触发双击的,不会双击和单击的都同时触发
在ViewDidLoad里面添加以下代码
UITapGestureRecognizer* singleRecognizer; singleRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(SingleTap:)]; singleRecognizer.numberOfTapsRequired = ; [self.view addGestureRecognizer:singleRecognizer]; UITapGestureRecognizer* doubleRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(DoubleTap:)]; doubleRecognizer.numberOfTapsRequired = ; [self.view addGestureRecognizer:doubleRecognizer]; [singleRecognizer requireGestureRecognizerToFail:doubleRecognizer];
在类里面添加以下方法
-(void)SingleTap:(UIPinchGestureRecognizer*)recognizer
{
NSLog(@"SingleTap");
}
-(void)DoubleTap:(UIPinchGestureRecognizer*)recognizer
{
NSLog(@"DoubleTap");
}
iOS学习笔记——触控与手势的更多相关文章
- iOS学习笔记——基础控件(上)
本篇简单罗列一下一些常用的UI控件以及它们特有的属性,事件等等.由于是笔记,相比起来不会太详细 UIView 所有UI控件都继承于这个UIView,它所拥有的属性必是所有控件都拥有,这些属性都是控件最 ...
- IOS 学习笔记(6) 控件 文本域(UITextField)的使用方法
UITextField控件的诸多特性都和UITextView相似,比如成为输入文本焦点时键盘自动显示,支持长按弹出动作选项,能够接收输入事件(开始输入,修改内容,结束输入和点击回车等). 1.特有的特 ...
- ios 学习笔记之控件属性
1.文本框 设置密码属性:Secure Text Entry 勾选; 设置文本框带清除属性: Clear Button =Is always visible; 默认是不带清除属性:Never app ...
- IOS 学习笔记(7) 控件 分隔栏控件(UISegmentControl)的使用方法
分隔栏控件的系统默认式样一共有3种,分别是“普通式样”,"边框式样","条状式样" 分隔栏控件中有一个momentary属性,默认时NO.当开发者配置成YES时 ...
- IOS 学习笔记(5) 控件 文本视图(UITextView)的使用方法
相对于UILabell所支持的较短文本内容,UITextView对于长文本的支持更好.UITextView能够以滚动的方式全部浏览到长文本,并且就像UILabel那样,从ISO6,他也提供了对NSAt ...
- IOS 学习笔记(4) 控件 标签(UILabel)的使用方法
虽说Label的中文翻译是标签标记,但它其实是一个静态文本内容的展现控件. 一般来说,UILabel只是一个只读的文本视图,开发者可以利用UiLabel来展示内容长度有固定上限的文字内容.并且,UIL ...
- ios 学习笔记(8) 控件 按钮(UIButton)的使用方法
在实际开发中,对于开发者来说,更多的还是使用“自定义”按钮.将“按钮”对象的类型设置成UIButtonTypeCustom.这样一来,按钮的所有元素都将由开发者来配置和自定义. 对于一个自定义按钮来说 ...
- IOS学习笔记(四)之UITextField和UITextView控件学习
IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...
- iOS学习笔记-自定义过渡动画
代码地址如下:http://www.demodashi.com/demo/11678.html 这篇笔记翻译自raywenderlick网站的过渡动画的一篇文章,原文用的swift,由于考虑到swif ...
随机推荐
- Python--增量循环删除MySQL表数据
需求场景: 有一业务数据库,使用MySQL 5.5版本,每天会写入大量数据,需要不定期将多表中“指定时期前“的数据进行删除,在SQL SERVER中很容易实现,写几个WHILE循环就搞定,虽然MySQ ...
- 渣渣小本求职复习之路每天一博客系列——数据库基础(MySQL)(5)
前情回顾:昨天学习了MySQL中索引的设计与使用,还了解了一些常见的SQL注入攻击的手段以及防范方法,一般来说,在面试的时候如果不是要求比较高,基本就够用了. 今天碰见一个拿了TP-LINK的offe ...
- 剑英陪你玩转图形学(五)focus
很久没来和大家交流业务(zhuangbi)水平了,最近实在是很忙,报名了小游戏大赛,一点时间都抽不出,已经坑了. 今天抓紧时间和大家介绍一个小效果: 新手引导的时候,我们会需要一种全屏幕黑掉,只有一个 ...
- js 把url参数转对象
//注意url中要含? function getParameterByName(name, url) { if (!url) { url = win ...
- nginx负载下站点错误响应会导致其他节点重复响应问题的解决过程
目录 前言 问题来了 问题又来了 问题分析 困惑 转机 后续 前言: 这是我上周工作过程中的一次解决问题的过程.解决的是nginx负载下站点错误响应导致其他节点重复响应. 我在整理这个记叙文时,在给这 ...
- 缓存篇(Cache)~第二回 使用static静态成员实现服务器端缓存(导航面包屑)~续
返回目录 在写完首篇cache文章后,有些朋友给我来信,希望可以使用JS的方法来实现这个导航功能,所以,才有了这篇文章,JS与C#不同,它虽然有引用类型,但它不具备一些引用类型的特性,如它的方法参数为 ...
- DDD~领域事件中使用分布式事务
回到目录 对于一个聚合来说,它可能会被附加很多事件,这里我们叫它领域事务,因为一个聚会我们可以把它理解成一个领域,一个业务.对于领域事件不清楚的同学可以看看我的这篇文章<DDD~领域事件与事件总 ...
- fir.im Weekly - 给 Mac 应用开发者的教程
写作是一件苦差事.无论写代码,还是写文章. 关于 Mac 应用开发,国内很少有完整的书籍或教程.最近@剑指人心写的 <Mac 应用开发基础教程>终于!完!稿!了! 这本书中对 Mac 平台 ...
- fir.im Weekly - 热门 iOS 第三方库大盘点
本期 fir.im Weekly 收集的热度资源,大部分关于Android.iOS 开发工具.源码和脑洞大开的 UI 动画,希望给你带来更多的工作创意与灵感. 盘点国内程序员不常用的热门iOS第三方库 ...
- WPF入门教程系列九——布局之DockPanel与ViewBox(四)
七. DockPanel DockPanel定义一个区域,在此区域中,您可以使子元素通过描点的形式排列,这些对象位于 Children 属性中.停靠面板其实就是在WinForm类似于Dock属性的元 ...