前言

小伙伴们在开发中是否遇到过这样的需求呢,一个控件的某个部分被另外一个控件遮挡住,当点击这个重叠部分时,需要响应被遮盖控件的点击事件,就如下图所示

 

当我们点击区域3时,响应蓝色按钮的点击事件,点击区域1和2时,响应红色按钮的点击事件,对于区域1和3没什么好说的,那如何让红色按钮响应区域2的点击呢?这就是笔者今天要讲的内容。

事件传递

大家应该都知道,事件从应用程序开始,按照从上到下的顺序(UIApplication -> UIWindow -> rootViewController -> ...)一级一级传递,并且系统在寻找最适合处理事件的控件时,是从后往前遍历子控件的(网上资料太多,不做详细阐述,请自行百度)

上图中蓝色按钮在红色按钮之后添加,当系统寻找最适合的控件时,蓝色按钮在红色按钮之前被找到,系统发现蓝色按钮很适合处理事件,所以方法便返回了,红色按钮就没有了处理事件的机会。

系统如何寻找最适合控件

  • 判断自己能否接受触摸事件,如果不能,返回nil
  • 判断触摸点是否在自己身上,如果不能,返回nil
  • 从后往前遍历子控件,重复上面的步骤,如果没有适合的子控件,返回自己

我们来看看系统内部是如何实现的,笔者这里自定义了一个UIWindow,让它成为主窗口,并重写它的hitTest方法,运行之后,其事件处理功能,与系统的类似,所以系统内部大概就是这样实现的

 

当一个控件的透明度小于某个值时,就不再响应事件,上图中0.01仅仅是为了测试,并非准确的值,要注意的就是,对于继承自UIControl的控件,还需要判断enable的值

事件穿透

既然系统寻找最合适控件的方法满足不了我们,那我们就重写系统的方法

思路
  • 点击蓝色按钮的区域2,红色按钮响应事件,那肯定要重写蓝色按钮的hitTest方法
  • 在hitTest方法中,将触摸点的坐标系从蓝色按钮转换到红色按钮上,即以红色按钮左上角为原点
  • 坐标系转换后,判断触摸点是否在红色按钮上,如果是,直接返回红色按钮(严谨一点的做法是调用红色按钮的hitTest方法),如果不是,那就调用系统的方法,让系统去处理

有了思路,那万事具备只欠东风了,接下来上东风

新建一个类,继承自UIButton,笔者这里直接命名为BlueButton,修改sb\xib中蓝色按钮的类型为BlueButton

 

将红色按钮连线到BlueButton.m文件中,不用试了,直接连是连不了的,我们可以先在BlueButton.m中定义一个属性,前面加上IBOutlet,然后单击图中的空心圆,拖到红色按钮上就OK了

 

 

最后,在BlueButton.m中重写蓝色按钮的hitTest方法,代码如下

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
CGPoint redBtnPoint = [self convertPoint:point toView:_redButton];
if ([_redButton pointInside:redBtnPoint withEvent:event]) {
return _redButton;
}
//如果希望严谨一点,可以将上面if语句及里面代码替换成如下代码
//UIView *view = [_redButton hitTest: redBtnPoint withEvent: event];
//if (view) return view;
return [super hitTest:point withEvent:event];
}

来看运行结果,点击区域2时,红色按钮高亮并响应事件

 

iOS之事件穿透的更多相关文章

  1. 支持事件穿透?使用pointer-events样式

    使用绝对定位元素,让元素A完全盖住元素B时,如何通过元素A来响应元素B的事件呢? 上图可以用下面的SVG代码来实现: <svg width="200" height=&quo ...

  2. 手机端 zepto tap事件穿透

    什么是事件穿透? 点击上面的一层时会触发下面一层的事件 ”google”说原因是“tap事件实际上是在冒泡到body上时才触发”,也就是Zepto的tap事件是绑定在document上的,所以会导致 ...

  3. IOS触摸事件和手势识别

    IOS触摸事件和手势识别 目录 概述 触摸事件 手势识别 概述 为了实现一些新的需求,我们常常需要给IOS添加触摸事件和手势识别 触摸事件 触摸事件的四种方法 -(void)touchesBegan: ...

  4. IOS——触摸事件 视图检测和事件传递

    iPhone上有非常流畅的用户触摸交互体验,能检测各种手势:点击,滑动,放大缩小,旋转.大多数情况都是用UI*GestureRecognizer这样的手势对象来关联手势事件和手势处理函数.也有时候,会 ...

  5. IOS 触摸事件分发机制详解

    欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~ 作者:MelonTeam 前言 很多时候大家都不关心IOS触摸事件的分发机制的实现原理,当遇到以下几种情形的时候你很可能抓破头皮都找不到解决方案 ...

  6. 如何让触摸事件穿透一个View

    如何让触摸事件穿透一个View 偶然间发现,如何屏蔽或者让触摸事件穿透一个view是一个很简单的事情. 现象: 源码: // // ViewController.m // UserInteractio ...

  7. Jquery 在ios上事件委托失效

    点击通过js遍历出来的列表,跳转页面.点击事件委托在document上, 像这样: $(document).on("click",".nav",function ...

  8. [原创]实现多层DIV叠加的js事件穿透

    Flash里面有个很好的特性是,一个容器里,不存在实际对象的部分,不会阻拦鼠标事件穿透到下一层. 前端就不一样了,两个div层叠以后,上层div会接收到所有事件(即使这个div里面内容是空的,没有任何 ...

  9. iOS开发事件分发机制—响应链—手势影响

    1.提纲 什么是iOS的事件分发机制 ? 一个事件UIEvent又是如何响应的? 手势对于响应链有何影响? 2.事件分发机制 2.1.来源 以直接触摸事件为例: 当用户一个手指触摸屏幕是会生成一个UI ...

随机推荐

  1. 静态Web开发 HTML

    静态Web开发 一章 HTML(Hyper Text Markup Language) 1节html入门 HTML超文本标记语言由浏览器解释执行开发人员编写的超文本文档就是网页 XHTMLHTML升级 ...

  2. C# 中的枚举类型 enum (属于值类型)

    原文 C# 中的枚举类型 enum (属于值类型) C# 支持两种特殊的值类型:枚举和结构. 声明枚举:声明时要声明所有可能的值. using System; using System.Collect ...

  3. [Bhatia.Matrix Analysis.Solutions to Exercises and Problems]ExI.5.2

    The elementary tensors $x\otimes \cdots \otimes x$, with all factors equal, are all in the subspace ...

  4. alibaba笔试3

    16.C 17.这道的取值范围应该是1到1023.这样就选择A 18.B 圆桌问题1个人拿出来当key 19.D 类似于https://apollozhao.wordpress.com/categor ...

  5. 【管理工具】Kerberos简单应用

    Kerberos这一名词来源于希腊神话“三个头的狗——地狱之门守护者”系统设计上采用客户端/服务器结构与DES加密技术,并且能够进行相互认证,即客户端和服务器端均可对对方进行身份认证.可以用于防止窃听 ...

  6. javascript 的 split用法

    var array = "200,400,300".split(","); var nums = [ ]; for (var i=0 ; i< array ...

  7. Spring MVC整合logback日志框架实战

    1.引入依赖,本项目maven构建,普通项目导入想要的jar包即可 版本 <properties> <slf4j-api.version>1.7.7</slf4j-api ...

  8. Spark环境的搭建与运行

    Spark本地安装与配置 下载spark后解压,并cd到解压目录下 运行实例程序测试是否一切正常 ./bin/run-example org.apache.spark.examples.SparkPi ...

  9. BNUOJ-29364 Bread Sorting 水题

    题目链接:http://www.bnuoj.com/bnuoj/problem_show.php?pid=29364 题意:给一个序列,输出序列中,二进制1的个数最少的数.. 随便搞搞就行了,关于更多 ...

  10. [学姿势]实验室搬砖+node学习

    这周开始进行收尾工作,我当然没有进行核心技术的开发,主要负责的是对web端进行展示上的修修补补,主要包括添加VLC播放器.rtsp视频流以及一些js细节. 1.VLC 全称为Video Lan Cli ...