iOS的触控事件是基于多点触控模型。
一、触控可以概述为:
1.触控是用户手指触碰屏幕,或触碰屏幕并在屏幕上移动时,系统不间断发送给应用程序的“对象”。
2.系统把事件按照特定的路径传递给可以处理事件的“对象”。
3.在iOS中,一个触摸表示一个UITouch对象;一个UITouch对象表示一个事件。
4.事件的对象包含与当前多点触摸序列对应的所有触摸对象,也可以提供和特定视图(或窗口)关联的触摸事件。
二、触控的开始、移动和结束:
触摸信息有时间和空间两项。
1.时间上的信息称为阶段(有四个阶段)
(1)触摸是否开始、(2)是否移动中、(3)停止中、(4)停止的时刻。
2.触摸信息中也包括当前视图的位置信息,在窗口中的的位置信息。
3.手指接触屏幕时,触摸会和某个窗口(或视图)关联,这个关联在事件的生命周期都回得到维护。
触控有关的术语:
1.“手势” 手指接触屏幕开始,直到手指离开屏幕为止发生的所有事件;
2.“触摸” 手指放到屏幕上拖动。
3.“轻击” 手指触摸屏幕,并立即离开的动作。
三、Cocoa中,代表触摸的对象的类是UITouch。
UITouch类中包含5个属性:
1.window:触摸产生所在的窗口。(窗口可变,所以不一定是最开始是的窗口)
2.view:触摸产生时所在的视图。(视图可变,所以不一定是最开始是的视图)
3.tapCount:轻击(Tap)操作和鼠标单击操作一样。(TapCount表示短时间内轻击屏幕的次数)
4.timestamp:时间戳用来记录触摸事件产生和变化的时间。(单位秒)
5.phase:触摸事件在屏幕上的周期。(触摸开始、触摸移动、中途取消、触摸结束)
phase UITouchPhase类型的,是一个枚举:
(1)UITouchPhaseBegan:触摸开始;
(2)UITouchPhaseMove:接触点移动;
(3)UITouchPhaseStationary:接触点无移动;
(4)UITouchPhaseEnded:触摸结束
(5)UITouchPhaseCancelled:触摸取消
四、触控事件的响应链
UIResponder 响应者:
-所有的事件响应的类都是UIResponder的子类。
(即UIResponder是所有事件响应的基类,并为所有响应事件进行处理,和提供通用的响应行为处理。)
-UIView及所有所有作为UIview子类的UIKit类(包括Window)都直接或间接的继承UIResponser
(所有这些类的实例都是响应对象)
-在iOS中,一个UIResponder对象表示一个可以接受触摸屏上触摸事件的对象。(既一个可以接收事件的对象)
-响应者,可以响应三种类型的事件:1.触控事件;2.motion事件;3.remove事件。
-Responser提供的四个响应触控事件的方法,这个四个方法是触摸事件捕捉的核心。
(这些方法都接收两个参数,一个NSSet,一个UIEvent)
-UIEvent对象包含一组相关的UITouch对象。
(可以理解为一个完整的的触摸操作是一个UIEvent,完整的操作就是UITouch包括(按下,移动,离开))
-UIEvent的作用的作用就是提供触摸事件的相关操作列表。
(可以使用该对象来获取在屏幕上的操作手势,这些操作都存储在Foundation框架中的NSSet对象中。)
-NSSet存放的是UITouch对象。
(UITouch对象是手指接触屏幕做移动(或离开屏幕)时创建)
lacationInView:此方法可以触摸在指定视图中的当前位置
previousLocationView:此方法可以触摸在指定视图中的前一个位置。
NSSet主要的时间控制方法是在给定的触摸阶段中。发生新的触摸动作或已有的触摸动作发生变化,应用程序会发送消息:
=手指触碰屏幕时,发送touchesBegan:withEvent:消息;
=手指在屏幕上移动,发送tochesMoved:withEvent:消息;
=手指离开屏幕时,发送touchsEnded:withEvent:消息
=当触摸序列被取消(如电话呼入),发送touchesCancelled:withEvent:消息
触控事件的响应链:
控件响应触碰时间的时候,有先后的顺序。有一个第一响应者(即受到触控事件时,会第一个响应触控事件的控件,这个响应者一般都是用户正在交互的对象)
响应链:
响应链就是一系列已经连接的响应者对象。(事件和消息通过连接的路径进行传递)
诺干响应者链接的响应链中,如果第一响应者(或视图)不处理消息,UIkit会通过消息的形式把事件转发到第一响应者的下一个响应者,此时再看这个第二响应者是处理这个消息,如果不处理接着传递。(在响应链中,允许响应者把事件处理的责任传递给高层的其他响应者)
响应链要有一系列的下一个响应者,每个下一个响应者可以通过nextResponser方法来得到。
响应链的规则
1.第一响应者就是响应链的开始
2.以UIResponder为父类的任何类都是响应者
3.如果第一响应者不处理某事件,则这个事件会传递给响应者链中的下一级,如果下一级处理,就停止事件的传递。
4.如果事件通过整个响应者链后,并且没有对象处理这个事件,那么这个事件会被丢弃。
在iOS中,由响应链来对事件进行响应,所有事件的响应的类都是UIResponder的子类。因为响应者链是一个不同对象组成的层级结构,所以每个对象都会以此获得响应事件消息的机会。(直到事件被处理才会停止)
响应链传递顺序的总结:
1.第一响应者几乎总是视图或控件,并且首先对事件进行响应;
2.如果第一响应者不处理,便传递给自身的视图控制器,如果仍不处理变传递给第一响应者的父视图;
3.如果父视图没有处理,便转到父视图的控制器;
4.如果一直传递,任何链节都没有处理,最终会传递到应用程序的窗口;
5.如果窗口不处理,便会传递给应用程序委托,如果应用程序委托不是UIResponder子类(或不处理),最终这个事件会被丢弃。
响应链中传递触控事件的方法
利用响应者的父类UIResponder提供的四个方法,实现将事件传递给下一个传递者。
[self.nextResponder touchesBegan:touches withEvent:event];
步奏:
1.首先定义一个视图,并实现UIResponder提供的四个方法中的其中一个;
2.在里面先简单的打印本视图的名字,然后再将触控事件传递给下一个响应者;
3.最后在视图控制器中创建三个视图,并让这三个视图重叠在一起,点击按钮,通过控制台来观察触控事件的传递顺序。
步奏1.新创建一个Cocoa Touch类,用来创建视图
得到新创建的类的文件(自定义视图类文件)
步奏2.在MyView.h文件中添加一个字符串(自定义视图h文件)
#import
@interfaceMyView :UIView
@property(retain,nonatomic)NSString*name;//添加一个的全局字符串变量name
@end
步奏3.在MyView.m文件中添加代码(自定义视图m文件)
#import"MyView.h"
@implementationMyView
/**
*创建视图
*/
-(id)initWithFrame:(CGRect)frame//初始化器
{
self= [superinitWithFrame:frame];
if(self)
{
}
returnself;
}
/**
*响应触摸事件的代码
*/
-(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
NSLog(@"%@",self.name);//输出方法
[self.nextRespondertouchesBegan:toucheswithEvent:event];
}
@end
步奏4.在ViewController.h文件中添加方法名(视图控制器h文件)
#import
#import"MyView.h"
@interfaceViewController :UIViewController
@property(retain,nonatomic)MyView* view1;
@property(retain,nonatomic)MyView* view2;
@property(retain,nonatomic)MyView* view3;
@end
步奏5.在ViewController.m文件中实现具体操作(视图控制器m文件)
#import"ViewController.h"
@interfaceViewController()
@end
@implementationViewController
- (void)viewDidLoad
{
//添加第一个红色视图
[superviewDidLoad];
self.view1=[[MyViewalloc]initWithFrame:CGRectMake(20,50,280,280)];
self.view1.backgroundColor= [UIColorredColor];
//添加第二个绿色视图
self.view2=[[MyViewalloc]initWithFrame:CGRectMake(40,40,200,200)];
self.view2.backgroundColor= [UIColorgreenColor];
//添加第三个蓝色视图
self.view3=[[MyViewalloc]initWithFrame:CGRectMake(40,40,120,120)];
self.view3.backgroundColor= [UIColorblueColor];
//三个视图输出的内容
self.view1.name=@"红视图,编号1,位于底部";
self.view2.name=@"绿视图,编号2,位于中部";
self.view3.name=@"蓝视图,编号3,位于底部";
//添加视图到本视图中
[self.view2addSubview:self.view3];
[self.view1addSubview:self.view2];
[self.viewaddSubview:self.view1];
}
- (void)didReceiveMemoryWarning
{
[superdidReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end