iOS--子视图如何穿透上层视图响应事件
一、使用方法:
- (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event;
二.背景知识
iOS系统检测到手指触摸(Touch)操作时会将其放入当前活动Application的事件队列,Application会从事件队列中取出触摸事件并传递给key window(当前接收用户事件的窗口)处理,window对象首先会使用hitTest:withEvent:方法寻找此次Touch操作初始点所在的视图(View),即需要将触摸事件传递给其处理的视图,称之为hit-test view。
window对象会在首先在view hierarchy的顶级view上调用hitTest:withEvent:,此方法会在视图层级结构中的每个视图上调用pointInside:withEvent:,如果pointInside:withEvent:返回YES,则继续逐级调用,直到找到touch操作发生的位置,这个视图也就是hit-test view。
三、处理流程
1.首先调用当前视图的pointInside:withEvent:方法判断触摸点是否在当前视图内;
2.若返回NO,则hitTest:withEvent:返回nil;
3.若返回YES,则向当前视图的所有子视图(subviews)发送hitTest:withEvent:消息,所有子视图的遍历顺序是从
top到bottom,即从subviews数组的末尾向前遍历,直到有子视图返回非空对象或者全部子视图遍历完毕;
4.若第一次有子视图返回非空对象,则hitTest:withEvent:方法返回此对象,处理结束;
5.如所有子视图都返回非,则hitTest:withEvent:方法返回自身(self)。
四、代码示例
// 在父视图中实现方法
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
// 1.这是当前点击的视图,如果没有找到合适的响应操作的视图,则直接返回这个
UIView *view = [super hitTest:point withEvent:event];
// 2.将父视图坐标转成我想要响应事件的视图的坐标
CGPoint buttonPoint = [self convertPoint:point toView:self.button];
// 3.判断该坐标是否在视图内部,如果是,则返回该视图
if ([self.button pointInside:buttonPoint withEvent:event]) {
return self.button;
}
return view;
}
五、注意事项
1.设置hidden = YES;仍然是可以通过该方法响应事件。
2.设置alpha = 0.001;也是可以通过该方法响应事件。
3.子视图的 origin 即使超出父视图的范围也是可以响应事件。
4.设置userInteractionEnabled = NO;则不可以响应事件了。
by:lm
iOS--子视图如何穿透上层视图响应事件的更多相关文章
- iOS 开发经验谈,点击没响应事件
- UIImageView中的UIButton不响应事件解决方案
如下: CGRect imageRect = (CGRect){, , , }; UIImageView *imageView = [[[UIImageView alloc] initWithFram ...
- IOS子视图超过父视图frame后,无法交互响应
确定第一响应者 当用户触发某一事件(触摸事件或运动事件)后,UIKit会创建一个事件对象(UIEvent),该对象包含一些处理事件所需要的信息.然后事件对象被放到一个事件队列中.这些事件按照先进先出的 ...
- 让超出父视图范围的子视图响应事件,在UIView范围外响应点击
/** * 在父视图中重写该方法,这样可使超出部分响应事件. */ - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { ...
- ios 透过上层视图点击相应下方视图的点击事件
- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event{ UIView *hitView = [super hitTest:point ...
- iOS开发app启动原理及视图和控制器的函数调用顺序
main()函数是整个程序的入口,在程序启动之前,系统会调用exec()函数.在Unix中exec和system的不同在于,system是用shell来调用程序,相当于fork+exec+waitpi ...
- iOS企业级开发初级课程-表视图(13集)
首先了解了表视图的组成.表视图类的构成.表视图的分类以及表视图的两个重要协议(委托协议和数据源协议),对表视图有了一个整体上的认识.接下来我们掌握了如何实现简单表视图和分节表视图,以及表视图中索引.搜 ...
- 使用AppDelegate单例,解决子视图无法给父视图发送消息的问题
关于单例模式,我会在实验过后再开一个博客重点讲单例的使用,这里只是介绍我在PhotoForBingyan的照片滤镜的项目中使用AppDelegate单例的情况. 碰到的问题: 由于这个项目是个多视图的 ...
- Xamarin iOS教程之添加和定制视图
Xamarin iOS教程之添加和定制视图 Xamarin iOS用户界面——视图 在iPhone或者iPad中,用户看到的摸到的都是视图.视图是用户界面的重要组成元素.例如,想要让用户实现文本输入时 ...
随机推荐
- uva1422 二分法+优先队列贪心
题意:有n个任务,每个任务必须在在时刻[r, d]之内执行w的工作量(三个变量都是整数).处理器执行的速度可以变化,当速度为s时,一个工作量为w的任务需要 执行的时间为w/s个单位时间.另外不一定要连 ...
- GIt-恢复进度
继续暂存区未完成的实践 经过了前面的实践,现在DEMO版本库应该处于master分支上,看看是不是这样. $ cd /path/to/my/workspace/demo $ git status -s ...
- MySQL之架构与历史(一)
MySQL架构与历史 和其他数据库系统相比,MySQL有点与众不同,它的架构可以在多种不同的场景中应用并发挥好的作用,但同时也会带来一点选择上的困难.MySQL并不完美,却足够灵活,它的灵活性体现在很 ...
- mybatis特殊字符处理
在mybatis 的mapper.xml文件中特殊字符处理方式 仅供参考 出处:http://yaobenzhang.blog.163.com/blog/static/214395113201561 ...
- angular用$sce服务来过滤HTML标签
angular js的强大之处之一就是他的数据双向绑定这一牛B功能,我们会常常用到的两个东西就是ng-bind和针对form的ng-model.但在我们的项目当中会遇到这样的情况,后台返回的数据中带有 ...
- 一道题目关于Java类加载
public class B { public static B t1 = new B(); public static B t2 = new B(); { System.out.println(&q ...
- leetcode NO.171 Excel表列序号 (python实现)
来源 https://leetcode-cn.com/problems/excel-sheet-column-number/description/ 题目描述 给定一个Excel表格中的列名称,返回其 ...
- idea的ssm搭建(复制)
1.工具/原料 • apache-tomcat-7.0.63 http://download.csdn.net/detail/lxfhahaha/9778163 • apache-maven-3.3. ...
- algorithm 头文件
非修改性序列操作(12个) 循环 对序列中的每个元素执行某操作 for_each() 查找 在序列中找出某个值的第一次出现的位置 find() 在序列中找出符合某谓词的第一个元素 find_if() ...
- 【bzoj1095】[ZJOI2007]Hide 捉迷藏 动态点分治+堆
题目描述 捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉迷藏游戏.他们的家很大且构造很奇特,由N个屋子和N-1条双向走廊组成,这 ...