iOS_触摸事件与手势识别
目 录:
一、触摸事件
1.1iOS的输入事件
1.2 触摸事件的处理
1.3 UITouch类中包含五个属性
1.4 UITouch类中包含两个成员函数
1.5响应者链
二、手势识别
2.1使用手势处理器(UIGestureRecognizer)
2.2案例分析
1.触摸事件:通过触摸、手势进行触发(例如手指点击、缩放)
2.运动事件:通过加速器进行触发(例如手机晃动)
3.远程控制事件:通过其他远程设备触发(例如耳机控制按钮)
下图是苹果官方对于这三种事件的形象描述:

iOS中许多事件对象都是UIEvent类的实例,UIEvent记录了事件所产生的时刻和事件类型。通过UIEvent对象的type属性可以获取事件的类型。在iOS中不是任何对象都能处理事件,只有继承了UIResponser的对象才能接收并处理事件。我们称之为“响应者对象”。UIApplication,UIViewController,UIView都继承自UIResponser,因此它们都是响应者对象,都能够接收并处理事件。
在以下三种情况下,不能接收事件
1.与用户交互的属性设为NO
2.hideen设为YES(隐藏)
3.alpha=0(透明)
1.2 触摸事件的处理
UIView是UIResponder的子类,可以覆盖下列4个方法处理不同的触摸事件。
1. 一根或者多根手指开始触摸屏幕
2.一根或者多根手指在屏幕上移动(随着手指的移动,会持续调用该方法)
3.一根或者多根手指离开屏幕
4.触摸结束前,某个系统事件(例如电话呼入)会打断触摸过程
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
1.3 UITouch类中包含五个属性
- window:触摸产生时所处的窗口。由于窗口可能发生变化,当前所在的窗口不一定是最开始的窗口
- view:触摸产生时所处的视图。由于视图可能发生变化,当前视图也不一定时最初的视图
- tapCount:点按操作和鼠标的单击操作类似,tapCount表示短时间内点按屏幕的次数。因此可以根据tapCount判断单击、双击或更多的点按
- timestamp:时间戳记录了触摸事件产生或变化时的时间,单位是秒
- phase:触摸事件在屏幕上有一个周期,即触摸开始、触摸点移动、触摸结束,还有中途取消。通过phase可以查看当前触摸事件在一个周期中所处的状态。phase是UITouchPhase类型的,是一个枚举配型,包含:
1.4 UITouch类中包含两个成员函数
1) - (CGPoint)locationInView:(UIView *)view:
返回一个CGPoint类型的值,表示触摸在view这个视图上的位置,这里返回的位置是针对view的坐标系的。调用时传入的view参数为空的话,返回的时触摸点在整个窗口的位置
2) - (CGPoint)previousLocationInView:(UIView *)view:
1.5响应者链

#import "ViewController.h" @interface ViewController ()
@end
@implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
//支持多点触摸
self.view.multipleTouchEnabled = YES;
//接受用户触摸交互
self.view.userInteractionEnabled = YES;
}
//当用户手指开始接触控件或窗口事件时激发该方法
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
/*
知识点补充:
1.当某个UIView发生触摸事件时,系统会将和事件相关的UITouch对象作为参数传入
2.因为可以有多根手指同时触发同一个事件,所以传给视图的是一组UITouch对象,保存在NSSet中,例如:
1)如果两根手指同时触摸某个视图,那么touchesBegan:withEvent:的第一个参数是包含两个UITouch实例的NSSet对象;
2)如果这两根手指一前一后分开触摸同一个视图,那么视图会收到两个独立的touchesBegan:withEvent:消息,并且每个NSSet对象中只包含一个UITouch对象
因此,根据NSSet中UITouch的个数可以判断出是单点触摸还是多点触摸
*/
NSLog(@"触摸点击");
//通过读取touches创建新的UITouch对象
UITouch *touch = [touches anyObject]; //取出当前点击的坐标点
CGPoint location = [touch locationInView:self.view]; //取出上一个坐标点(适用于移动情况下,如果只是纯粹的两次触摸点击,无效果)
CGPoint previousLocation = [touch previousLocationInView:self.view];
//打印输出坐标点
NSLog(@"%@,%@",NSStringFromCGPoint(location),NSStringFromCGPoint(previousLocation)); //输出所有的UITouch对象
// NSLog(@"%@",[touches allObjects]);
}
//当用户手指结束触摸控件时激发该方法
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"触摸结束");
}
//当用户手指在控件上移动时激发该方法
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"触摸移动");
}
//当系统事件(比如内存低事件)中止了触碰事件时激发该方法
-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"取消触摸");
} @end
二、手势识别
2.1使用手势处理器(UIGestureRecognizer)
| UITapGestureRecognizer | 点按手势 |
| UIPinchGestureRecognizer | 捏合手势 |
| UIPanGestureRecognizer | 拖动手势 |
|
UISwipeGestureRecognizer
|
轻扫手势(滑动手势),支持四个方向的轻扫,但是不同的方向要分别定义轻扫手势
|
| UIRotationGestureRecognizer | 旋转手势 |
| UILongPressGestureRecognizer | 长按手势 |
#import "ViewController.h" @interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *myView; @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
//设置myView控件支持用户交互
self.myView.userInteractionEnabled = YES;
//设置myView控件支持多点触碰
self.myView.multipleTouchEnabled = YES;
//一、tap手势
//创建手势处理器,指定使用该控制器的tap:方法处理手势
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tap:)];
//指定该手势处理器只处理几次触碰事件
tap.numberOfTapsRequired = ;
//指定该手势处理器只处理几个手指的触碰事件
tap.numberOfTouchesRequired = ;
//为myView控件添加手势处理器
[self.myView addGestureRecognizer:tap]; } //实现手势处理器的方法,该方法应该声明一个形参
//当该方法被激发时,手势处理器会作为参数传给该方法的参数
-(void)tap:(UITapGestureRecognizer *)sender
{
UIView *view = sender.view;
if ([sender.view.backgroundColor isEqual:[UIColor redColor]])
{
view.backgroundColor = [UIColor greenColor];
}
else
{
view.backgroundColor = [UIColor redColor];
}
} @end
#import "ViewController.h" @interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *myView; @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
//设置myView控件支持用户交互
self.myView.userInteractionEnabled = YES;
//设置myView控件支持多点触碰
self.myView.multipleTouchEnabled = YES;
//二、pinch手势(放大、缩小)(捏合)
UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(pinch:)];
[self.view addGestureRecognizer:pinch];
} //实现手势处理器的方法,该方法应该声明一个形参
//当该方法被激发时,手势处理器会作为参数传给该方法的参数
-(void)pinch:(UIPinchGestureRecognizer *)sender
{
if (sender.state == UIGestureRecognizerStateRecognized)
{
//1.使用仿射变换获取当前的状态
CGAffineTransform transform = self.myView.transform;
//2.按照变换系数对view进行变换
transform = CGAffineTransformScale(transform, sender.scale, sender.scale);
//3.按照新的仿射变换进行变换视图
self.myView.transform = transform;
}
}
@end
2.2.3使用UIRotationGestureRecognizer处理旋转手势
#import "ViewController.h" @interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *myView; @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
//设置myView控件支持用户交互
self.myView.userInteractionEnabled = YES;
//设置myView控件支持多点触碰
self.myView.multipleTouchEnabled = YES; //三、Rotain手势(旋转)
UIRotationGestureRecognizer *rotain = [[UIRotationGestureRecognizer alloc]initWithTarget:self action:@selector(rotain:)];
//给view控件添加手势处理器
[self.view addGestureRecognizer:rotain];
} -(void)rotain:(UIRotationGestureRecognizer *)sender
{
if (sender.state == UIGestureRecognizerStateChanged)
{
//方式一:
//使用放射变换进行旋转
// self.myView.transform = CGAffineTransformMakeRotation(sender.rotation); //方式二:
//1.使用仿射变换获取当前的状态
CGAffineTransform transform = self.myView.transform;
//2.按照变换系数对view进行变换
transform = CGAffineTransformRotate(transform, sender.rotation);
//3.按照新的仿射变换进行变换视图
self.myView.transform = transform;
}
sender.rotation = ;
/*
方式一与方式二的区别在于:
在执行之后方式一不需要进行复位操作,方式二需要进行复位。以防影响下一次操作。
注意:复位不是必须的,可以根据开发者的需要进行选择是否需要进行复位操作。
*/
} @end
2.2.4使用UISwipeGestureRecognizer处理轻扫手势
#import "ViewController.h" @interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *myView; @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
//设置myView控件支持用户交互
self.myView.userInteractionEnabled = YES;
//设置myView控件支持多点触碰
self.myView.multipleTouchEnabled = YES;
//六、swipe手势(轻扫)
UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipe:)];
// swipe.direction = UISwipeGestureRecognizerDirectionRight | UISwipeGestureRecognizerDirectionLeft; [self.view addGestureRecognizer:swipe];
} -(void)swipe:(UISwipeGestureRecognizer *)sender
{
if (sender.direction == UISwipeGestureRecognizerDirectionRight)
{
NSLog(@"swipe right");
}
else if (sender.direction == UISwipeGestureRecognizerDirectionLeft)
{
NSLog(@"swipe left");
}
else if (sender.direction == UISwipeGestureRecognizerDirectionUp)
{
NSLog(@"swipe up");
}
else if (sender.direction == UISwipeGestureRecognizerDirectionDown)
{
NSLog(@"swipe down");
}
}
@end
2.2.5使用UIPanGestureRecognizer处理拖动手势
#import "ViewController.h" @interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *myView; @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
//设置myView控件支持用户交互
self.myView.userInteractionEnabled = YES;
//设置myView控件支持多点触碰
self.myView.multipleTouchEnabled = YES;
//四、pan手势(拖动)
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(pan:)];
//指定该手势处理器处理的最小手指数
pan.minimumNumberOfTouches = ;
//指定该手势处理器处理的最da手指数
pan.maximumNumberOfTouches = ;
[self.myView addGestureRecognizer:pan];
}
-(void)pan:(UIPanGestureRecognizer *)sender
{
//判断手势的状态
if (sender.state == UIGestureRecognizerStateChanged)
{ CGPoint offSetPoint = [sender translationInView:self.view];
CGPoint center = self.myView.center;
self.myView.center = CGPointMake(center.x+offSetPoint.x, center.y+offSetPoint.y);
// CGPoint velocity = [sender velocityInView:self.myView];
// CGPoint translation = [sender translationInView:self.myView];
// NSLog(@"%@,%@",velocity,translation);
}
//进行复位操作
[sender setTranslation:CGPointZero inView:self.view];
}
@end
#import "ViewController.h" @interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *myView; @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
//设置myView控件支持用户交互
self.myView.userInteractionEnabled = YES;
//设置myView控件支持多点触碰
self.myView.multipleTouchEnabled = YES;
//五、longPress手势(长按)
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPress:)];
//指定该手势处理器只处理几个手指的触碰事件
longPress.numberOfTouchesRequired = ;
//长按的持续时间(按住多久之后才算做是长按)
longPress.minimumPressDuration = 0.5f;
//为控件添加长按手势
[self.myView addGestureRecognizer:longPress];
}
-(void)longPress:(UILongPressGestureRecognizer *)sender
{
if (sender.state == UIGestureRecognizerStateChanged)
{
self.myView.backgroundColor = [UIColor yellowColor];
}
else if (sender.state == UIGestureRecognizerStateEnded)
{
self.myView.backgroundColor = [UIColor redColor];
}
}
@end
知识扩充:UIView的常用方法
iOS_触摸事件与手势识别的更多相关文章
- iOS开发系列--触摸事件、手势识别、摇晃事件、耳机线控
-- iOS事件全面解析 概览 iPhone的成功很大一部分得益于它多点触摸的强大功能,乔布斯让人们认识到手机其实是可以不用按键和手写笔直接操作的,这不愧为一项伟大的设计.今天我们就针对iOS的触摸事 ...
- IOS触摸事件和手势识别
IOS触摸事件和手势识别 目录 概述 触摸事件 手势识别 概述 为了实现一些新的需求,我们常常需要给IOS添加触摸事件和手势识别 触摸事件 触摸事件的四种方法 -(void)touchesBegan: ...
- 转发:iOS开发系列--触摸事件、手势识别、摇晃事件、耳机线控
-- iOS事件全面解析 转载来自崔江涛(KenshinCui) 链接:http://www.cnblogs.com/kenshincui/p/3950646.html 概览 iPhone的成功很大一 ...
- 触摸事件,手势识别(UITouch,UIGestureRecognizer)
触摸发生时,UIWindow会有一个队列来存放所有的触摸事件,然后再把这些事件发送给对应的hit-test view,hit-test view会通过touch的四个函数来接收这些事件. 四个函数分别 ...
- iOS:触摸事件和手势识别的介绍
触摸事件和手势识别的介绍 1.iOS的输入事件 UIKit可识别三种类型的输入事件: 触摸事件 运动事件 远程控制事件 iOS中许多事件对象都是UIEvent类的实例,UIEvent记录了事件所产生 ...
- 【iOS系列】-触摸事件与手势识别
[iOS系列]-触摸事件与手势识别 第一:触摸事件 一根手指触摸屏幕时,会创建一个与手指相关联的UITouch对象 UIEvent:称为事件对象,记录事件产生的时刻和类型 两根手指同时触摸一个view ...
- iOS基础 - 触摸事件与手势识别
一.iOS的输入事件 UIKit可识别三种类型的输入事件: 触摸事件 运动(加速计)事件 远程控制事件 二.UIEvent iOS中许多事件对象都是UIEvent类的实例,记录事件产生的时刻和类型 U ...
- iOS中的触摸事件,手势识别,摇晃事件等
在iOS中,事件可以划分为以下几类: 1.触摸事件:通过触摸,手势进行触发(手指点击.缩放等) 2.运动事件:通过加速器触发(例如手机晃动) 3.远程控制事件:通过其他远程设备触发(例如耳机控制按钮) ...
- iOS-触摸事件、手势识别、摇晃事件、耳机线控
概览 iPhone的成功很大一部分得益于它多点触摸的强大功能,乔布斯让人们认识到手机其实是可以不用按键和手写笔直接操作的,这不愧为一项伟大的设计.今天我们就针对iOS的触摸事件(手势操作).运动事件. ...
随机推荐
- Oracle数据迁移expdp/impdp
Oracle数据迁移expdp/impdp目的:指导项目侧自行进行简单的数据泵迁移工作. 本文实验环境:Oracle 11.2.0.4,利用数据库自带的scott示例用户进行试验测试. 1.首先需要创 ...
- PPT常用操作笔记
1. 组合就是框成一组 2. 页与页之间的播放运作及效果设置“切换”,页内的元素过滤设置“动画” 3. 转PDF:PDF打印机或直接来个金山WPS 4. 讲义打印,要点:灰度.去深色背景.多页,弄了个 ...
- 编写gulpfile.js文件:压缩合并css、js
使用gulp一共有四个步骤: 1. 全局安装 gulp: $ npm install --global gulp 2. 作为项目的开发依赖(devDependencies)安装: $ npm inst ...
- MathType编辑表示右上角的符号的方法
MathType是一款公式编辑器,其中的符号种类非常的全,如果需要编辑一些专业的公式,用它非常的方便快捷.但是有些符号由于不常用,在一些模板之中使用的时候需要深入地去查找调用一下.比如表示右上角的符号 ...
- 服务器之ECC报错检查
需要使用ipmitool工具 [root@Resource ~]# yum install ipmitool 首先查看是否有ecc报错 如下图: [root@Resource ~]# ipmitool ...
- [Unity热更新]tolua# & LuaFramework(一):基础
一.tolua# c#调用lua:LuaState[变量名/函数名] 1.LuaState a.执行lua代码段 DoString(string) DoFile(.lua文件名) Require(.l ...
- Android开发:《Gradle Recipes for Android》阅读笔记(翻译)2.4——更新新版本的Gradle
问题: 你需要更新应用的Gradle版本. 解决方案: 生成一个新的wrapper,或者直接修改属性文件(.properties). 讨论: Android Studio包含了一个Gradle的分发. ...
- ofstream和ifstream详细用法
ASCII和二进制文件的输入输出 First:包含头文件#include <fstream> ASCII输入: 首先要创建一个in-stream对象:ifstream fin(" ...
- tomcat访问日志分析
常使用web服务器的朋友大都了解,一般的web server有两部分日志: 一是运行中的日志,它主要记录运行的一些信息,尤其是一些异常错误日志信息 二是访问日志信息,它记录的访问的时间,IP,访问的资 ...
- 第一次打开Pycharm如何操作?
1.第一次打开pycharm的界面: 2.一些pycharm的选择: 3.上一步,红字4的位置,点击进去,对下面界面进行选择,也就是选择System Interpreter解释器,然后对Interpr ...