事件处理

⼀、事件的基本概念
  • 事件  是当⽤户⼿指触击屏幕及在屏幕上移动时,系统不断 发送给应⽤程序的  对象。
  • 系统将事件按照特定的路径传递给可以对其进⾏处理的对 象。
  • 在iOS中,⼀个UITouch对象表⽰⼀个触摸,⼀个UIEvent 对象表⽰⼀个事件。事件对象中包含与当前多点触摸序列 相对应的所有触摸对象,还可以提供与特定视图或窗⼝相 关联的触摸对象。
  • 事件类型:触摸事件、晃动事件、远程事件
 
⼆、触摸的基本概念
在给定的触摸阶段中,如果发⽣新的触摸动作或已有的触摸动作发⽣ 变化,应⽤程序就会发送这些消息:
当⼀个或多个⼿指触碰屏幕时,发送touchesBegan:withEvent:消息。
当⼀个或多个⼿指在屏幕上移动时,发送touchesMoved:withEvent:消 息。
当⼀个或多个⼿指离开屏幕时,发送touchesEnded:withEvent:消息。
 
三、响应者链
  • 响应者链是⼀个响应者对象的连接序列,事件或动作消息 (或菜单编辑消息)依次传递。它允许响应者对象把事件 处理的职责转交给其它更⾼层的对象。应⽤程序通过向上 传递⼀个事件来查找合适的处理对象。因为点击检测视图 也是⼀个响应者对象,应⽤程序在处理触摸事件时也可以 利⽤响应链。 
  • 由多个响应者对象组成的链。
  • iOS中所有能响应事件(触摸、晃动、远程事件)的对象 都是响应者。 
  • 系统定义了⼀个抽象的⽗类UIResponder来表⽰响应者。 其⼦类都是响应者。
 
检测碰撞视图
硬件检测到触摸操作,会将信息交给UIApplication,开始检测。
UIApplication -> window -> viewController -> view -> 检测所有⼦ 视图
最终确认触碰位置,完成响应者链的查询过程。
 
处理触摸事件
检测到响应者后,实现touchesBegan:withEvent:等⽅法,即处理事 件。
如果响应者没有处理事件,事件会向下传递。如果没有响应者处理, 则丢弃触摸事件。
事件处理的顺序与触摸检测查询相反。
触摸的⼦视图 -> view -> viewController -> window -> UIApplication
 
阻断响应者链
响应者链可以被打断。⽆法完成检测查询过程。
视图类的属性 : userInteractionEnabled。关闭后能阻断查询过 程。
 
响应者链处理原则
点击检测视图或者第⼀响应者传递事件或动作消息给它的视图控制器(如 果它有的话);如果没有⼀个视图控制器,就传递给它的⽗视图。 
如果⼀个视图或者它的视图控制器不能处理这个事件或动作消息,它将 传递给该视图的⽗视图。
在这个视图层次中的每个后续的⽗视图遵循上述的模式,如果它不能处 理这个事件或动作消息的话。
最顶层的视图如果不能处理这个事件或动作消息,就传递给UIWindow对 象来处理。
如果UIWindow 对象不能处理,就传给单件应⽤程序对象UIApplication 如果应⽤程序对象也不能处理这个事件或动作消息,将抛弃它。
 
//打开用户交互
    imageView.userInteractionEnabled = YES;
    //响应者链阻断之后,完成不了检测过程。检测过程完成不了,所以事件就触发不了。
    //而控件阻断响应者链就是关闭用户交互,默认关闭用户交互的控件有UIImageView和UILabel.
    //以后的项目开发中,如果想让UIImageView和UILabel响应事件,必须将其交互打开
 
 
//触摸的三个时间阶段的方法
//触摸开始的方法
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"%s %d",__FUNCTION__, __LINE__);
    self.backgroundColor = [UIColor colorWithRed:arc4random() % 256 / 255.0 green:arc4random() % 256 / 255.0 blue:arc4random() % 256 / 255.0 alpha:1.0];
    /*
    //记录屏幕的宽和高
    CGFloat screenWidth = [[UIScreen mainScreen] bounds].size.width;
    CGFloat screenHeight = [[UIScreen mainScreen] bounds].size.height;
   
    int minX = (int)(self.frame.size.width / 2);
    int maxX = (int)(screenWidth) - minX;
   
    int minY = (int)(self.frame.size.height / 2);
    int maxY = (int)(screenHeight) - minY;
   
    CGPoint newCenter = CGPointMake(0, 0);
    newCenter.x = arc4random() % (maxX - minX + 1) + minX;
    newCenter.y = arc4random() % (maxY - minY + 1) + minY;
    self.center = newCenter;*/
}

//触摸移动的方法
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"%s %d",__FUNCTION__, __LINE__);
    self.backgroundColor = [UIColor colorWithRed:arc4random() % 256 / 255.0 green:arc4random() % 256 / 255.0 blue:arc4random() % 256 / 255.0 alpha:1.0];
   
    //获取触摸在屏幕上的手指对象
    UITouch *touch = [touches anyObject];
   
    //获取手指之前的屏幕上的位置
    CGPoint previousP = [touch previousLocationInView:self];
   
    //获取手指现在的屏幕上的位置
    CGPoint currentP = [touch locationInView:self];
   
    CGPoint newCenter = CGPointMake(0, 0);
    newCenter.x = self.center.x + (currentP.x - previousP.x);
    newCenter.y = self.center.y + (currentP.y - previousP.y);
    self.center = newCenter;
}

//触摸结束的方法
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"%s %d",__FUNCTION__, __LINE__);
}
 
 
 
 
 
 
原文地址:https://www.cnblogs.com/Walking-Jin/p/5210812.html