iOS 事件分类及事件分发机制
什么是事件分发机制,当用户触碰屏幕后,其事件的传递过程被称作事件的分发,IOS的事件分发机制大致原理与Android及其相似。该事件传递过程往往都是由父控件一步一步向其子控件进行分发的。
事件分类
在Ios中事件被分为了3类:
- 触摸事件:手指触碰屏幕时触发的事件。
- 加速事件:当手机加速度改变时触发的时间(列如摇一摇)。
- 远程控制事件:当用户使用远程遥控设备时触发的事件。
哪些View可以响应事件
继承自UIResponder的类都可以响应事件的分发。所以UIApplication,UIView,UIViewController以及它们的子类均可以响应事件的分发和处理。
UIResponder中的常用方法
触摸事件:
//当触碰开始时触发
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
//当触碰开始后且在控件内移动时触发
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
//当触碰结束时触发
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
//当触碰被取消时触发(该情况一般是因为某一外部事件突然占用了屏幕时会触发,如突然有电话进入时)
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
//3D触碰时触发
- (void)touchesEstimatedPropertiesUpdated:(NSSet<UITouch *> *)touches NS_AVAILABLE_IOS(9_1);
加速事件:
//开始加速时触发
- (void)motionBegan:(UIEventSubtype)motion withEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(3_0);
//结束加速时触发
- (void)motionEnded:(UIEventSubtype)motion withEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(3_0);
//加速取消时触发
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(3_0);
远程遥控事件:
//远程遥控事件触发
- (void)remoteControlReceivedWithEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(4_0);
UITouch
什么是UITouch,我们可以将其想象成于手指相关联的一个对象,往往会被用来处理多点触碰,当一只手指触碰屏幕是,就会有一个UITouch对象返回,当有多只手指触碰屏幕时,就会有多个UITouch对象返回,它们是通过List来存储的。
UITouch的重要属性:
//当前触碰点所在window
@property(nullable,nonatomic,readonly,strong) UIWindow *window;
//当前触碰点所在视图
@property(nullable,nonatomic,readonly,strong) UIView *view;
//短时间内点击屏幕的次数
@property(nonatomic,readonly) NSUInteger tapCount;
//事件发生所用时间
@property(nonatomic,readonly) NSTimeInterval timestamp;
//当前触碰状态(枚举类)
@property(nonatomic,readonly) UITouchPhase phase;
//触碰类型(枚举类)
@property(nonatomic,readonly) UITouchType type;
//手指与屏幕的接触半径
@property(nonatomic,readonly) CGFloat majorRadius;
//手指与屏幕的接触半径误差值
@property(nonatomic,readonly) CGFloat majorRadiusTolerance;
//获取屏幕手势
@property(nullable,nonatomic,readonly,copy)NSArray <UIGestureRecognizer *> *gestureRecognizers;
//触碰屏幕的压力值(通常为1)
@property(nonatomic,readonly) CGFloat force;
//最大压力值
@property(nonatomic,readonly) CGFloat maximumPossibleForce;
UITouch的重要方法:
//返回当前触碰的视图
- (CGPoint)locationInView:(nullable UIView *)view;
//返回前一个触碰点的视图
- (CGPoint)previousLocationInView:(nullable UIView *)view;
//当前触碰视图所在的视图(父视图)
- (CGPoint)preciseLocationInView:(nullable UIView *)view;
//前一个触碰视图所在的视图(父视图)
- (CGPoint)precisePreviousLocationInView:(nullable UIView *)view;
事件分发机制(hitTest)
Ios事件分发,是从window开始向其子控件传递,其子控件又作为父控件向子控件进行分发的,如果子控件可以处理该事件则该事件有子控件处理,如果所有子控件无法处理该事件,则该事件会交由父控件处理。例如下图:如果我们点击了绿色View,该事件将会由Controller开始向内分发经过红色->蓝色->绿色,然后绿色View处理该事件,该过程的本质就是找到一个最适合处理该事件的View。 那么源码中是怎么实现这一过程的呢?hitTest方法和pointInside方法来共同实现寻找最适合处理该事件的View,所有的View都含有这两个方法,pointInside方法在hitTest方法中被调用,用于判断触碰点是否在该View内返回YES或者NO,而hitTest方法的则就是寻找最适合View的本质方法,其返回值为View
hitTest方法做了什么
- 判断当前View能否响应事件
- 触碰点是否在该View内部
- 从后往前遍历所有子控件判断子控件是否更合适响应该事件
- 如果没有合适的子控件来响应事件,则交给该View本身来处理事件
模拟hitTest内部实现
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {//判断自己能否响应事件if(self.userInteractionEnabled == NO||self.hidden == YES|| self.alpha <= 0.01){return nil;}//2.判断当前点在不在该View内部if(![self pointInside:point withEvent:event]){return nil;}//3.从后往前遍历自己的子控件,让子控件执行其hitTest方法for(UIView view in self.subviews){//将点切换为子view坐标系上的点CGPoint childPoint =[self convertPoint:point toView:view];UIView fitView = [view hitTest:childPoint withEvent:event];if(fitView){return fitView;}}return self;
}
哪些视图无法处理事件
- 当userInteractionEnabled = NO时无法处理事件(如果父视图的userInteractionEnabled=NO,则子视图同样无法处理事件)
- 当View被隐藏时无法处理事件(当父视图被隐藏时,其子视图也会被隐藏)
- 当alpha值为0.0 ~ 0.01时无法处理事件(同样如果父视图alpha值为0.0 ~ 0.01,子视图也无法处理事件)
iOS 事件分类及事件分发机制相关推荐
- 自定义View(二)--表层浅析View的事件分发机制和滑动冲突
转载请注明出处:From李诗雨:http://blog.csdn.net/cjm2484836553/article/details/54387722 不诗意的女程序猿不是好厨师~ 这篇文章来得有些曲 ...
- iOS开发事件分发机制—响应链—手势影响
1.提纲 什么是iOS的事件分发机制 ? 一个事件UIEvent又是如何响应的? 手势对于响应链有何影响? 2.事件分发机制 2.1.来源 以直接触摸事件为例: 当用户一个手指触摸屏幕是会生成一个UI ...
- 事件分发机制并不是洪水猛兽
文章目录 OnTouchListener与OnClickListener的优先级 事件分发 滑动冲突 处理滑动冲突 1. 内部拦截法 2.外部拦截法 当MotionEvent产生后,系统总归要将其传递 ...
- Android开发指南!Android事件分发机制收藏这一篇就够了,2年以上经验必看
前言 现在的终端开发已经开始进入稳定期,在这个阶段大厂压力很大小厂更会收到挤压,人们使用的App越来越固定,即使是大厂,几年前平台级应用发个Push就能引流几十万,现在这些的作用也越来越小,特别到了今 ...
- Android事件分发机制完全解析,带你从源码的角度彻底理解(上)
<div id="container"> <div id="header"> <div class=&qu ...
- View事件分发机制(源码 API27)
1.什么是事件分发机制 当用户触摸屏幕时,会产生一个touch事件,这个touch事件(motionEvent)传递到某个具体的view处理的整个过程 用户触摸屏幕会产生一个事件流(ACTION_DO ...
- Android事件分发机制详解
2019独角兽企业重金招聘Python工程师标准>>> 之前在学习Android事件方法机制的时候,看过不少文章,但是大部分都讲的不是很清楚,我自己理解的也是云里雾里,也尝试过阅读源 ...
- android触摸事件分发,Android 事件分发机制
Android 事件分发机制一直让人头痛,之前也是面向 GitHub 编程得过且过.今天下定决心了解一下,以便后面自己定制 View 效果.Android 触摸事件有三个基本类型:ACTION_DOW ...
- View事件分发机制(源码分析篇)
01.Android中事件分发顺序 1.1 事件分发的对象是谁 事件分发的对象是事件.注意,事件分发是向下传递的,也就是父到子的顺序. 当用户触摸屏幕时(View或ViewGroup派生的控件),将产 ...
最新文章
- AI一分钟|阿里成立“罗汉堂”;vivo微信人脸识别支付下半年商用
- 18秋c语言程序设计作业答案,[四川大学]《C语言程序设计0008》19秋在线作业2
- c++11-std::functionbind
- debugging Auto Layout:Logical Errors
- 腾讯三面:40亿个QQ号码如何去重?
- LINUX 文件合并,去重
- 现实中简单配置路由器
- 二叉搜索树(二叉排序树)
- 穆迪将收购信用数据和见解领导者Cortera
- vue第五天笔记02——vuex数据仓库
- Qt系列文章之 QAbstractItemModel(下)
- 惠普HP compaq康柏系列 CQ40笔记本电脑拆机除尘
- WordPress活动日历和预订插件指南
- php 红包过期退回,RabbitMQ功能实现1- 红包未领取退回
- 日本护照持有者可以免签进入全球193个目的地,创下历史记录
- 不同试验设计遗传力的计算方法
- 用soapUI测试GET/POST接口
- 中国幼儿教育市场运营模式与未来发展方向分析报告2022版
- 【重点警惕】.locked1后缀--TellYouThePass勒索病毒家族旗下勒索病毒
- 备考第3天:RHEL7 系统安装与基本调试