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中,用户看到的摸到的都是视图.视图是用户界面的重要组成元素.例如,想要让用户实现文本输入时 ...
随机推荐
- 第 8 章: 模块, 包与分发---Word
第八章: 模块, 包 与 分发 描述: 大型Python程序以模块和包的形式组织.另外,Python标准库中包含大量模块.本章详细介绍模块和包系统.还将提供有关如何安装第三方模块和分发源代码的信息. ...
- 笔记-网络-抓包-wireshark
笔记-网络-抓包-wireshark 1. 开始 环境:win8笔记本,无线网 1.1. 无线网卡设置 因为需抓捕无线网卡上的数据包,需要进行一项设置,如捕获有线网卡,无需设置. 打开 ...
- 消息框模块-tkinter
import tkinter.messagebox # 这个是消息框,对话框的关键from tkinter import * error_fp_list = [[973.45, '河北卡卡汽车贸易有限 ...
- RDLC Reporting in Visual Studio 2017
原文:RDLC Reporting in Visual Studio 2017 Visual Studio 2017 中可以使用 RDLC Reporting 插件来设计报表,SAP Crystal ...
- Codeforces 678F Lena and Queries
题意: 你有一个点集,有三种操作: 往集合里插入一个点\((x, y)\) 从集合中删除第\(i\)次操作插入的点 对于给出的\(q\),询问点集中\(x \cdot q + y\)的最大值 分析: ...
- Android 自定义debug.keystore
场景分析: 有时候,我们要使用第三方的服务,需要提供自己的包名以及keystore的sha1值,比如微信支付,百度地图,都需要包名和keystore的sha1值作为唯一标识.这时候我们测试的时候,如果 ...
- R语言分析朝阳医院数据
R语言分析朝阳医院数据 本次实践通过分析朝阳医院2016年销售数据,得出“月均消费次数”.“月均消费金额”.“客单价”.“消费趋势”等结果,并据此作出可视化图形. 一.读取数据: library(op ...
- Struts之上传
上传的jsp写法: <tr> <td width="50%" align="left">软件上传: <input type=&qu ...
- [netty4][netty-common]FastThreadLocal及其相关类系列
FastThreadLocal 概述: ThreadLocal的一个特定变种改善,有更好的存取性能. 内部采用一个数组来代替ThreadLocal内部的hash表来存放变量.虽然这看起来是微不足道的, ...
- (转载)django 访问url报错Forbidden (CSRF cookie not set.): xxx 问
原地址:http://www.cnblogs.com/meitian/p/7016336.html 问题:页面访问时报错 Forbidden (CSRF cookie not set.): xxx ...