一、事件的基本概念
UIEvent:事件,是由硬件捕捉的⼀个表⽰用户操作设备的对象。分三类:触摸事件、晃动事件、远程控制事件
触摸事件:⽤户通过触摸设备屏幕操作对象、输⼊数据。⽀持多点触摸,包含1个到多个触摸点
二、触摸的基本概念
1、实现触摸:
UIView⽀持触摸事件(因为继承于UIResponder),⽽且支持多点触摸。
需要定义UIView⼦类,实现触摸相关的⽅法。
touches..began、touches..moved、touches...ended、 touches..canceled。
2、使用触摸实现手势
⼿势:有规律的触摸。
UITouch代表触摸在屏幕上的⼀根⼿指。可以获取触摸时间和触摸位置。
如何获取touch对象。touches集合中包含了视图上的所有⼿势。
三、响应者链
响应者链:由多个响应者对象组成的链。
响应者:
UIResponder。响应者类。
iOS中所有能响应事件(触摸、晃动、远程事件)的对象都是响应者。
系统定义了⼀个抽象的⽗类UIResponder来表⽰响应者。其⼦类都是响应者。
检测触碰视图:
硬件检测到触摸操作,会将信息交给UIApplication,开始检测。
UIApplication -> window -> viewController -> view -> 检测所有⼦视图
最终确认触碰位置,完成响应者链的查询过程。
处理触碰事件:检测到响应者后,实现touchesBegan:withEvent:等⽅方法,即处理事件。
如果响应者没有处理事件,事件会向下传递。如果没有响应者处理,则丢弃触摸事件。
事件处理的顺序与触摸检测查询相反。
触摸的⼦视图 -> view -> viewController -> window -> UIApplication
阻断响应者链:
响应者链可以被打断。⽆法完成检测查询过程。
视图类的属性 : userInteractionEnabled。关闭后能阻断查询过程。
MyView.h文件的内容
@interface MyView : UIView
@property(nonatomic,retain) UIView *redView;
@property(nonatomic,assign) CGPoint startPoint;
@end
MyView.m文件的内容
@implementation MyView
- (void)dealloc
{
[_redView release];
[super dealloc];
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
//打开多点触摸。UIView默认是单点触摸
self.multipleTouchEnabled=YES;
self.backgroundColor=[UIColor cyanColor];
UIView *redView=[[UIView alloc]initWithFrame:CGRectMake(100, 100, 150, 150)];
redView.backgroundColor=[UIColor redColor];
[self addSubview:redView];
[redView release];
//属性与redView建立关联
self.redView=redView;
UIView *view=[[UIView alloc]initWithFrame:CGRectMake(20, 100, 100, 100)];
view.backgroundColor=[UIColor yellowColor];
//打断事件的交互
view.userInteractionEnabled=NO;
[self addSubview:view];
[view release];
UIButton *button=[UIButton buttonWithType:UIButtonTypeSystem];
button.frame=CGRectMake(10, 10, 40, 30);
button.backgroundColor=[UIColor redColor];
[button setTitle:@"button" forState:UIControlStateNormal];
[button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
[view addSubview:button];
}
return self;
}
- (void)buttonAction:(UIButton*)button
{
NSLog(@"buttonAction:");
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//获取触摸开始的点,并赋值给实例变量startPoint
CGPoint startPoint=[[touches anyObject] locationInView:self];
self.startPoint=startPoint;
//获取手指
UITouch *touch=[touches anyObject];
//打印点击次数
NSLog(@"点击%d次",touch.tapCount);
//改变redView的颜色
UIColor *randomColor=[UIColor colorWithRed:arc4random()%256/255.0 green:arc4random()%256/255.0 blue:arc4random()%256/255.0 alpha:1];
self.redView.backgroundColor=randomColor;
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
//打印函数名,行数
NSLog(@"%s %d",__FUNCTION__,__LINE__);
//打印手指的个数
NSLog(@"%d",touches.count);
//1.获取移动先前的一个位置
UITouch *touch=[touches anyObject];
CGPoint prePoint=[touch previousLocationInView:self];
//获取touch发生在哪个视图上
UIView *touchView=[touch view];
if (touchView==self.redView) {
//2.获取当前位置
CGPoint nowPoint=[touch locationInView:self];
//3.计算偏移量
float offsetX=nowPoint.x-prePoint.x;
float offsetY=nowPoint.y-prePoint.y;
//4.根据偏移量改变redView的位置
self.redView.center=CGPointMake(self.redView.center.x+offsetX, self.redView.center.y+offsetY);
}
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
//实现轻扫手势,并判断方向
//获取手指所在的位置,即触摸结束的位置
CGPoint endPoint=[[touches anyObject] locationInView:self];
//计算从触摸开始到结束的偏移量
float offsetX=endPoint.x-self.startPoint.x;
float offsetY=endPoint.y-self.startPoint.y;
//根据偏移量,确定是向哪个方向轻扫
if (offsetX>50&&fabs(offsetY)<=50) {
NSLog(@"向右");
}else if (offsetX<-50&&fabs(offsetY)<=50)
{
NSLog(@"向左");
}else if (fabs(offsetX)<50&&offsetY>50)
{
NSLog(@"向下");
}else if(fabs(offsetX)<50&&offsetY<-50){
NSLog(@"向上");
}
NSLog(@"%s %d",__FUNCTION__,__LINE__);
}
-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"%s %d",__FUNCTION__,__LINE__);
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
@end