3.6 事件

一. 事件

1. iOS中事件分为三种

  • 触摸
  • 加速计
  • 远程

2. 什么是响应者对象?

继承了UIResponds的对象我们称它为响应者对象

UIApplication、UIViewController、UIView都继承自UIResponder

因此它们都是响应者对象,都能够接收并处理事件

继承UIResponder称响应者对象

3. 事件调用方法

1> 触摸事件

  1. -(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event;
  2. -(void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event;
  3. -(void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event;
  4. -(void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event;

2> 加速计事件调用

  1. -(void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent*)event;
  2. -(void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent*)event;
  3. -(void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent*)event;

3> 远程控制事件

  1. -(void)remoteControlReceivedWithEvent:(UIEvent*)event;

4. 完整触摸过程

  1. 触摸开始:
  2. -(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
  3. 触摸移动:
  4. -(void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
  5. 触摸结束:
  6. -(void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
  7. 触摸取消(可能会经历,如来电时会调用):
  8. -(void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event

5. UIView拖拽

1> 自定义UIView,实现监听方法.

2> 确定在TouchMove方法当中进行操作,因为用户手指在视图上移动的时候才需要移动视图。

3> 获取当前手指的位置和上一个手指的位置.

4> 当前视图的位置 = 上一次视图的位置 + 手指的偏移量

关健代码实现:

  • 拿到UITouch就能获取当前点
  1. UITouch*touch =[touches anyObject];
  • 获取当前点
  1. CGPoint curP =[touch locationInView:self];
  • 获取上一个点
  1. CGPoint preP =[touch previousLocationInView:self];
  • 获取手指x轴偏移量
  1. CGFloat offsetX = curP.x - preP.x;
  • 获取手指y轴偏移量
  1. CGFloat offsetY = curP.y - preP.y;
  • 移动当前view
  1. self.transform =CGAffineTransformTranslate(self.transform, offsetX, offsetY);

二. 事件的产生和传递

1. 事件的产生和传递

当发生一个触摸事件后,系统会将该事件加入到一个由UIApplication管理的事件队列中.

UIApplication会从事件队列中取出最前面的事件,并将事件分发下去以便处理.

主窗口会在视图层次结构中找到一个最合适的视图来处理触摸事件

触摸事件的传递是从父控件传递到子控件的.

如果一个父控件不能接收事件,那么它里面的了子控件也不能够接收事件.

2. 一个控件什么情况下不能够接收事件

. 不接收用户交互时不能够处理事件

userInteractionEnabled = NO

. 当一个控件隐藏的时候不能够接收事件

Hidden = YES的时候

. 当一个控件为透明白时候也不能够接收事件

注意:UIImageView的userInteractionEnabled默认就是NO,因此UIImageView以及它的子控件默认是不能接收触摸事件的

3. 如何寻找合适的View

1> 先判断自己是否能够接收触摸事件,如果能再继续往下判断,

2> 再判断触摸的当前点在不在自己的身上.

3> 如果在自己身上,它会从后往前遍历子控件,遍历出每一个子控件后,重复前面的两个步骤.

4> 如果没有符合条件的子控件,那么它自己就是最适合的View.

4. hitTest方法与PointInside方法

1> hitTest方法寻找合适的View,只要一个事件传递给控件时就会调用

  1. -(UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event

2> PointInside方法判断当前点是否在此控件上(执行hitTest方法底层会调用此方法)

  1. -(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event{
  2.     return YES;
  3. }

注:point必须得要跟当前View同一个坐标系.

5. hitText方法底层实现原理

  1. //作用:寻找最适合的View
  2. //什么时候调用:当事件传递给当前View时就会调用这个方法
  3. -(UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event{
  4.  
  5.    //1.判断自己能否接收事件
  6.    if(self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <=0.01){
  7.        return nil;
  8.    }
  9.    //2.触摸点在不在自己身上
  10.    if([self pointInside:point withEvent:event]== NO){
  11.        return nil;
  12.    }
  13.    //3.从后往前遍历自己的子控件(重复前面的两个步骤)
  14.    
  15.    int count =(int)self.subviews.count;
  16.    //2,count i = 1 i = 0
  17.    for(int i = count -1; i >=0; i--){
  18.        
  19.        //取出子控件
  20.        UIView*childV = self.subviews[i];
  21.        //point必须得要跟childV相同的坐标系.
  22.        
  23.        //把point转换childV坐标系上面的点
  24.        CGPoint childP =[self convertPoint:point toView:childV];
  25.        UIView*fitView =[childV hitTest:childP withEvent:event];
  26.        if(fitView){
  27.            return fitView;
  28.        }
  29.    }
  30.    
  31.    //4.如果没有符合条件的子控件,那么就自己最适合处理
  32.    return self;
  33. }

三. 事件的响应和事件传递的完整过程

1. 事件响应

用户点击屏幕后产生的一个触摸事件,经过一系列的传递过程后,会找到最合适的视图控件来处理这个事件,

找到最合适的视图控件后,就会调用控件的touches方法来作具体的事件处理

那这些touches方法的默认做法是将事件顺着响应者链条向上传递,将事件交给上一个响应者进行处理

什么是响应者链条?

是由多个响应者对象连接起来的链条.

什么是响应者对象?

继承了UIResponder对象我们称之为响应者对象,也就是能处理事件的对象

2. 事件传递的完整过程?

在产生一个事件时,系统会将该事件加入到一个由UIApplication管理的事件队列中,

UIApplication会从事件队列中取出最前面的事件,将它传递给先发送事件给应用程序的主窗口.

主窗口会调用hitTest方法寻找最适合的视图控件,找到后就会调用视图控件的touches方法来做具体的事情.

当调用touches方法,它的默认做法, 就会将事件顺着响应者链条往上传递,

传递给上一个响应者,接着就会调用上一个响应者的touches方法

如何去寻找上一个响应者?

1.如果当前的View是控制器的View,那么控制器就是上一个响应者.

2.如果当前的View不是控制器的View,那么它的父控件就是上一个响应者.

3.在视图层次结构的最顶级视图,如果也不能处理收到的事件或消息,则其将事件或消息传递给window对象进行处理

4.如果window对象也不处理,则其将事件或消息传递给UIApplication对象

5.如果UIApplication也不能处理该事件或消息,则将其丢弃

来自为知笔记(Wiz)

时间: 2024-07-30 06:31:51

3.6 事件的相关文章

移动端点击事件全攻略,有你知道与不知道的各种坑

看标题的时候你可能会想,点击事件有什么好说的,还写一篇攻略?哈哈,如果你这么想,只能说明你too young to simple. 接触过移动端开发的同学可能都会面临点击事件的第一个问题:click事件的300ms延迟响应.不能立即响应给体验造成了很大的困扰,因此解决这个问题就成为了必然. 这个问题的解决方案就是: zepto.js的tap事件.tap事件可以理解为在移动端的click事件,而zepto.js因为几乎完全复制jQuery的api,因此常常被用在h5的开发上用来取代jquery.

js监控微信浏览器的自带的返回事件

pushHistory(); window.addEventListener("popstate", function(e) { e.preventDefault(); //alert("我监听到了浏览器的返回按钮事件啦"); //根据自己的需求实现自己的功能 //window.location = 'http://www.baidu.com'; pushHistory(); }, false); function pushHistory() { var state

微信小程序学习总结(2)------- 之for循环,绑定点击事件

最近公司有小程序的项目,本人有幸参与其中,一个项目做下来感觉受益匪浅,与大家做下分享,欢迎沟通交流互相学习. 先说一下此次项目本人体会较深的几个关键点:微信地图.用户静默授权.用户弹窗授权.微信充值等等. 言归正传,今天分享我遇到的关于wx:for循环绑定数据的一个tips:  1. 想必大家的都知道wx:for,如下就不用我啰嗦了: <view class="myNew" wx:for="{{list}}">{{item.title}}<view

touchstart和touchend事件

touchstart和touchend事件 移动互联网是未来的发展趋势,现在国内很多互联网大佬都在争取移动这一块大饼,如微信及支付宝是目前比较成功的例子,当然还有各种APP和web运用. 由于公司的需要,最近也在开发移动web,对于一个没有移动开发经验的人来说,其实也是比较困恼的一件事情.对于移动web开发目前主要是基于webkit内核的浏览器.在webkit内核的环境下开发,你可以充分的运用html5+css3,还有它的一些私有属性.这让我很兴奋.可是,毕竟,对于一个长期习惯pc端做固定像素开

苹果手机输入中文不会触发onkeyup事件

今天同事的项目有这个问题,用我的安卓手机输入中文是ok的,但是苹果手机就不行 使用keyup事件检测文本框内容:  $('#keyup_i').bind('keyup', function(){         $('#keyup_s').text($(this).val());  } 本来是上面这种处理方式,现在改成下面这样就ok了 使用oninput以及onpropertychange事件检测文本框内容:  //先判断浏览器是不是万恶的IE,没办法,写的东西也有IE使用者       var

离散事件模型

0x01 代码框架逻辑 模拟内容: 1.离散事件模拟,模拟银行营业时的排队情况 2.不考虑顾客中途离开,顾客到达事件随机,业务办理时间 3.长度随机,选择最短的队排队,不再换队 代码逻辑: 1.一个事件链表,四个窗口排队队列 2.事件驱动:每有一个新的顾客到达,将产生下一个新顾客到达的新事件按时间顺序从小到大(OccurTime)插入事件链表(EventList) (如果此时窗口队列只有 一个顾客,还将产生此顾客离开事件插入事件链表中)      每有一个顾客从某一队列首离开,将产生他的后一位顾

zepto事件

1.zepto的定义 Zepto是一个轻量级的针对现代高级浏览器的JavaScript库, 它与jquery有着类似的api 2.zepto与jq的区别 ①相同点:Zepto最初是为移动端开发的库,是jQuery的轻量级替代品,因为它的API和jQuery相似,而文件更小:zepto的API大部分都能和jQuery兼容,所以用起来极其容易 ②不同点: (1).针对移动端程序,Zepto有一些基本的触摸事件可以用来做触摸屏交互(tap事件.swipe事件) (2),Dom操作的区别:添加id时jQ

15.1-全栈Java笔记:Java事件模型是什么?事件控制的过程有哪几步??

应用前边两节上一章节的内容,大家可以完成一个简单的界面,但是没有任何的功能,界面完全是静态的,如果要实现具体功能的话,必须要学习事件模型. 事件模型简介及常见事件模型 对于采用了图形用户界面的程序来说,事件控制是非常重要的. 一个源(事件源)产生一个事件并把它(事件对象)送到一个或多个监听器那里,监听器只是简单地等待,直到它收到一个事件,一旦事件被接收,监听器将处理这些事件. 一个事件源必须注册监听器以便监听器可以接收关于一个特定事件的通知. 每种类型的事件都有其自己的注册方法,一般形式为: v

RecyclerView动态添加、删除及点击事件

上一节讲解了RecyclerView的三种显示方式,本节将主要研究一下RecyclerView的动态添加.删除及其单击和长按事件的处理.我们在上一节代码的基础上进行相关操作. 一.修改适配器类MyAdapter,加入添加和删除这两个方法: public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> { private Context context; private List<String>

事件(1)

事件三要素 事件源:事件发生的来源 事件:行为(点击,触摸...) 监听器:当事件发送时,所要做的事情  onClickListener(单击事件) 组件.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { String str=et.getText().toString(); tv.setText(str); } }); 1 public class Click extends Ac