13.1 事件概述
事件是当用户手指触击屏幕及在屏幕上移动时,系统不断发送给应用程序的对象。
系统将事件按照特定的路径传递给可以对其进行处理的对象。
在iOS中,一个UITouch对象表示一个触摸,一个UIEvent对象表示一个事件。事件对象中包含与当前多点触摸序列相对应的所有触摸对象,还可以提供与特定视图或窗口相关联的触摸对象。
响应者对象
响应者对象是可以响应事件并对其进行处理的对象。
UIResponder是所有响应者对象的基类,它不仅为事件处理,而且也为常见的响应者行为定义编程接口。
UIApplication、UIView、和所有从UIView派生出来的UIKit类(包括UIWindow)都直接或间接地继承自UIResponder类。
第一响应者是应用程序中当前负责接收触摸事件的响应者对象(通常是一个UIView对象)。UIWindow对象以消息的形式将事件发送给第一响应者,使其有机会首先处理事件。如果第一响应者没有进行处理,系统就将事件(通过消息)传递给响应者链中的下一个响应者,看看它是否可以进行处理。
![wps_clip_image-12891 wps_clip_image-12891](http://images.cnblogs.com/cnblogs_com/syxchina/201210/201210142313207241.png)
响应者链
响应链是一个响应者对象的连接序列,事件或动作消息(或菜单编辑消息)依次传递。它允许响应者对象把事件处理的职责转交给其它更高层的对象。应用程序通过向上传递一个事件来查找合适的处理对象。因为点击检测视图也是一个响应者对象,应用程序在处理触摸事件时也可以利用响应链。响应链由一系列的下一个响应者组成。
![wps_clip_image-22150 wps_clip_image-22150](http://images.cnblogs.com/cnblogs_com/syxchina/201210/20121014231321108.png)
响应者链处理原则
1. 点击检测视图或者第一响应者传递事件或动作消息给它的视图控制器(如果它有的话);如果没有一个视图控制器,就传递给它的父视图。
2. 如果一个视图或者它的视图控制器不能处理这个事件或动作消息,它将传递给该视图的父视图。
3. 在这个视图层次中的每个后续的父视图遵循上述的模式,如果它不能处理这个事件或动作消息的话。
4. 最顶层的视图如果不能处理这个事件或动作消息,就传递给UIWindow对象来处理。
5. 如果UIWindow 对象不能处理,就传给单件应用程序对象UIApplication。
如果应用程序对象也不能处理这个事件或动作消息,将抛弃它。
13.2 触摸事件
触摸信息有时间和空间两方面,时间方面的信息称为阶段(phrase),表示触摸是否刚刚开始、是否正在移动或处于静止状态,以及何时结束—也就是手指何时从屏幕抬起。触摸信息还包括当前在视图或窗口中的位置信息,以及之前的位置信息(如果有的话)。当一个手指接触屏幕时,触摸就和某个窗口或视图关联在一起,这个关联在事件的整个生命周期都会得到维护。
触摸事件的阶段
![wps_clip_image-20236 wps_clip_image-20236](http://images.cnblogs.com/cnblogs_com/syxchina/201210/201210142313255317.png)
事件处理方法
在给定的触摸阶段中,如果发生新的触摸动作或已有的触摸动作发生变化,应用程序就会发送这些消息:
当一个或多个手指触碰屏幕时,发送touchesBegan:withEvent:消息。
当一个或多个手指在屏幕上移动时,发送touchesMoved:withEvent:消息。
当一个或多个手指离开屏幕时,发送touchesEnded:withEvent:消息。
当触摸序列被诸如电话呼入这样的系统事件所取消时,发送touchesCancelled:withEvent:消息。
触摸事件实例 EventInfo
#import <UIKit/UIKit.h>
@interface TouchView : UIView {
}
- (void)logTouchInfo:(UITouch *)touch;
@end
@implementation TouchView
- (void)logTouchInfo:(UITouch *)touch {
CGPoint locInSelf = [touch locationInView:self];
CGPoint locInWin = [touch locationInView:nil];
NSLog(@" touch.locationInView = {%2.3f, %2.3f}", locInSelf.x, locInSelf.y);
NSLog(@" touch.locationInWin = {%2.3f, %2.3f}", locInWin.x, locInWin.y);
NSLog(@" touch.phase = %d", touch.phase);
NSLog(@" touch.tapCount = %d", touch.tapCount);
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(@"touchesBegan - touch count = %d", [touches count]);
for(UITouch *touch in event.allTouches) {
[self logTouchInfo:touch];
}
}
touch.phase,触摸事件的阶段。
touch.tapCount,触摸事件的轻碰次数,可以判断双击事件。
UIEvent 的allTouches方法,可以获得触摸点的集合,可以判断多点触摸事件。
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(@"touchesMoved - touch count = %d", [touches count]);
for(UITouch *touch in event.allTouches) {
[self logTouchInfo:touch];
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(@"touchesEnded - touch count = %d", [touches count]);
for(UITouch *touch in event.allTouches) {
[self logTouchInfo:touch];
}
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(@"touchesCancelled - touch count = %d", [touches count]);
for(UITouch *touch in event.allTouches) {
[self logTouchInfo:touch];
}
}
13.3 手势
手势在iPhone中很重要,手势就是手触摸屏幕的方式。
单碰击
双碰击
多点触摸(合拢和展开)
轻抚
… …
单碰击和双碰击实例:MultiTap
单碰击为红色,双碰击为蓝色
#import <UIKit/UIKit.h>
@interface MultiTapView : UIView {
}
@end
#import "MultiTapView.h"
@implementation MultiTapView
- (void)turnBlue {
self.backgroundColor = [UIColor blueColor];
}
- (void)turnRed {
self.backgroundColor = [UIColor redColor];
}
//START:code.MultiTapView.touchesBegan:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
if(touch.tapCount == 2) {
[[self class] cancelPreviousPerformRequestsWithTarget:self
selector:@selector(turnRed)
object:nil];
}
}
//END:code.MultiTapView.touchesBegan:
//START:code.MultiTapView.touchesEnded:
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
if(touch.tapCount == 1) {
[self performSelector:@selector(turnRed) withObject:nil afterDelay:0.10f];
}
if(touch.tapCount == 2) {
[self turnBlue];
}
}
//END:code.MultiTapView.touchesEnded:
@end
[self performSelector:@selector(turnRed) withObject:nil afterDelay:0.10f]; 是在0.1秒后调用turnRed方法。
[[self class]cancelPreviousPerformRequestsWithTarget:self selector:@selector(turnRed) object:nil]; 是取消调用方法turnRed。
多点触摸(合拢和展开)PinchZoom
![wps_clip_image-13471 wps_clip_image-13471](http://images.cnblogs.com/cnblogs_com/syxchina/201210/201210142313333379.png)
PinchZoomView .h文件
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
@interface PinchZoomView : UIView {
CALayer *robotLayer;
CGFloat previousDistance;
CGFloat zoomFactor;
BOOL pinchZoom;
}
@property(nonatomic, retain) CALayer *robotLayer;
@end
m文件
#import "PinchZoomView.h"
@implementation PinchZoomView
@synthesize robotLayer;
- (void)awakeFromNib {
self.robotLayer = [CALayer layer];
UIImage *image = [UIImage imageNamed:@"Robot.png"];
self.robotLayer.contents = (id)[image CGImage];
self.robotLayer.bounds = CGRectMake(0.0f, 0.0f, image.size.width, image.size.height);
self.robotLayer.position = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
[self.layer addSublayer:self.robotLayer];
pinchZoom = NO;
previousDistance = 0.0f;
zoomFactor = 1.0f;
}
awakeFromNib当nib文件被加载的时候,加载器会发送一个awakeFromNib的消息到nib文件中的每个对象,每个对象都可以定义自己的 awakeFromNib方法来响应这个消息,执行一些必要的操作。也就是说通过nib文件创建view对象是执行awakeFromNib 。
robotLayer是 CALayer 对象,本例子中我们把图片对象添加到robotLayer对象中。使用 CALayer需要引入 <QuartzCore/QuartzCore.h>头文件和添加QuartzCore.framework框架。
//START:code.PinchZoomView.touchesBegan
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if(event.allTouches.count == 2) {
pinchZoom = YES;
NSArray *touches = [event.allTouches allObjects];
CGPoint pointOne = [[touches objectAtIndex:0] locationInView:self];
CGPoint pointTwo = [[touches objectAtIndex:1] locationInView:self];
previousDistance = sqrt(pow(pointOne.x - pointTwo.x, 2.0f) +
pow(pointOne.y - pointTwo.y, 2.0f));
} else {
pinchZoom = NO;
}
}
//END:code.PinchZoomView.touchesBegan
previousDistance 是获得两个点的距离。
pow是平方函数。
sqrt是开平方根函数。
![wps_clip_image-12925 wps_clip_image-12925](http://images.cnblogs.com/cnblogs_com/syxchina/201210/201210142313375915.png)
//START:code.PinchZoomView.touchesMoved
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
if(YES == pinchZoom && event.allTouches.count == 2) {
NSArray *touches = [event.allTouches allObjects];
CGPoint pointOne = [[touches objectAtIndex:0] locationInView:self];
CGPoint pointTwo = [[touches objectAtIndex:1] locationInView:self];
CGFloat distance = sqrt(pow(pointOne.x - pointTwo.x, 2.0f) +
pow(pointOne.y - pointTwo.y, 2.0f));
zoomFactor += (distance - previousDistance) / previousDistance;
zoomFactor = fabs(zoomFactor);
previousDistance = distance;
self.robotLayer.transform = CATransform3DMakeScale(zoomFactor, zoomFactor, 1.0f);
}
}
//END:code.PinchZoomView.touchesMoved
//START:code.PinchZoomView.touchesEnded
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if(event.allTouches.count != 2) {
pinchZoom = NO;
previousDistance = 0.0f;
}
if(event.allTouches.count == 1) {
// NSArray *touches = [event.allTouches allObjects];
// UITouch *touch = [touches objectAtIndex:0];
UITouch *touch = [touches anyObject];
NSInteger tapCount = [touch tapCount];
if (tapCount == 2) {
zoomFactor += 0.4;
self.robotLayer.transform = CATransform3DMakeScale(zoomFactor, zoomFactor, 1.0f);
} else if (tapCount == 3) {
zoomFactor += 0.6;
self.robotLayer.transform = CATransform3DMakeScale(zoomFactor, zoomFactor, 1.0f);
} else if (tapCount == 4) {
zoomFactor += 0.8;
self.robotLayer.transform = CATransform3DMakeScale(zoomFactor, zoomFactor, 1.0f);
}
}
}
//END:code.PinchZoomView.touchesEnded
- (void)dealloc {
self.robotLayer = nil;
[robotLayer release];
[super dealloc];
}
分享到:
相关推荐
雨松MOMO Unity3D 游戏开发系列博文之Unity3D 游戏引擎之IOS触摸屏手势控制镜头旋转与缩放,欢迎大家下载阅读,哇咔咔~~
IOS_5手势识别教程:二指拨动、拖移以及更多手势详细教程
包含ios大部分触摸事件的执行流程,以及一些不常规的触摸事件处理方法
手势与触摸事件,基本属性和方法
IOS应用源码——ios触摸事件例子全集.zip
IOS应用源码之ios触摸事件例子全集.rar
IOS5.0后,手势识别可以直接拖动至UIViewController。这里时官网提供的代码下载。
简单易用的图形手势识别器,能够添加、删除和识别所有一笔画出的手势图案。 将该功能集成到App中,可以实现各种图案对应不同指令,例如画一个五角星打开聊天页面,画一个三角形打开评价页面等;也可以识别数字、...
触摸事件在IOS中是基于多点触摸模型。取代鼠标和键盘,用户通过触摸设备的屏幕来 操作对象,输入数据以及实现其它意愿。IOS识别的一个或多个手指对屏幕进行触摸并将其 作为多点触摸序列的一部分。该序列以用户第一个...
此Demo运用了iOS中所有常用手势,没有MVC的思想,直接写到控制器了,想了解手势的朋友们可看看!愿朋友工作顺心!
本文给大家汇总介绍了在IOS开发中我们经常需要用到的手势识别的相关知识,非常的细致全面,有需要的小伙伴可以参考下
iOS TableView 添加手势方法
iOS手势识别入门及使用,包含Pinch、Pan、Swipe、Rotation、Long Press、Tap这6种手势代码,均使用stroryboard,xcode7.0下编译
UIImageView默认是不支持交互的,也就是userInteractionEnabled=NO ,因此要接收触摸事件(手势识别),必须设置userInteractionEnabled=YES(在iOS中UILabel、UIImageView的userInteractionEnabled默认都是NO,...
操作系统:支持Ios 7.0 硬件配置:推荐ARM Cortex-A7以上,1G RAM 摄像头:支持自动对焦,200万像素以上 安装程序占用空间,2MBytes
最简单的iOS触摸实现示例工程源码。有一个视图,视图中有一个可以拖动位置的按钮。
在window上展示一张图片,可单击全屏,复原 ,双击放大缩小,捏合手势操作,唯一的缺点没加异步加载,后期会加上
手势识别器(Gesture Recognizer)用于识别触摸序列并触发响应事件。当手势识别器识别到一个手势或手势发生变化时,会触发响应事件。UIGestureRecognizer类作为抽象类,不能直接使用。只能使用UIGestureRecognizer的...