事件处理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了事件处理相关的知识,希望对你有一定的参考价值。

?、事件的基本概念
  • 事件  是当?户?指触击屏幕及在屏幕上移动时,系统不断 发送给应?程序的  对象。
  • 系统将事件按照特定的路径传递给可以对其进?处理的对 象。
  • 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__);
}
 
 
 
 
 
 

以上是关于事件处理的主要内容,如果未能解决你的问题,请参考以下文章

如何处理片段上的触摸事件?

处理Fragment类ListView的按钮事件?

Android 事件分发事件分发源码分析 ( Activity 中各层级的事件传递 | Activity -> PhoneWindow -> DecorView -> ViewGroup )(代码片段

C# 中 XBOX 控制器的事件处理程序?

处理recyclerview单击片段而不是持有者类

将通知设置为在某个用户事件时触发