首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

使用hitTest:withEvent捕获其超级视图框架外的子视图的触摸:

使用hitTest:withEvent捕获其超级视图框架外的子视图的触摸事件,可以通过以下步骤实现:

  1. 首先,需要在父视图中重写hitTest:withEvent方法,以便在触摸事件发生时检查子视图的位置。
  2. hitTest:withEvent方法中,获取当前触摸点的位置,并将其转换为父视图的坐标系中的位置。
  3. 遍历父视图中的所有子视图,检查它们的框架是否包含当前触摸点的位置。
  4. 如果找到了包含当前触摸点的子视图,则返回该子视图,以便系统将触摸事件发送到该子视图。
  5. 如果没有找到包含当前触摸点的子视图,则返回父视图本身,以便系统将触摸事件发送到父视图。

以下是一个示例代码:

代码语言:objective-c
复制
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    // 将触摸点转换为父视图的坐标系中的位置
    CGPoint pointInParentView = [self convertPoint:point fromView:self.superview];
    
    // 遍历父视图中的所有子视图
    for (UIView *subview in self.subviews) {
        // 检查子视图的框架是否包含当前触摸点的位置
        if (CGRectContainsPoint(subview.frame, pointInParentView)) {
            // 如果找到了包含当前触摸点的子视图,则返回该子视图
            return subview;
        }
    }
    
    // 如果没有找到包含当前触摸点的子视图,则返回父视图本身
    return self;
}

通过以上代码,可以在父视图中捕获子视图的触摸事件,即使子视图的框架超出了父视图的框架。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

IOS开发系列——UIView专题之五:常用开发技巧篇

操作初始点所在的视图(View),即需要将触摸事件传递给其处理的视图,称之为hit-test view。...hitTest:withEvent:方法的处理流程如下: •首先调用当前视图的pointInside:withEvent:方法判断触摸点是否在当前视图内; •若返回NO,则hitTest:withEvent...:返回nil; •若返回YES,则向当前视图的所有子视图(subviews)发送hitTest:withEvent:消息,所有子视图的遍历顺序是从top到bottom,即从subviews数组的末尾向前遍历...,直到有子视图返回非空对象或者全部子视图遍历完毕; •若第一次有子视图返回非空对象,则hitTest:withEvent:方法返回此对象,处理结束; •如所有子视图都返回非,则hitTest:withEvent...如果一个子视图的区域超过父视图的bound区域(父视图的clipsToBounds属性为NO,这样超过父视图bound区域的子视图内容也会显示),那么正常情况下对子视图在父视图之外区域的触摸操作不会被识别

1.2K20

【IOS开发基础系列】UIView专题

如果这个点位于接收者之外就返回nil 讨论         这个方法贯穿视图的层次发送pointInside:withEvent:消息到每一个子视图用来决定那个子视图需要接收触摸事件。...如果pointInside:withEvent: 返回YES,那么视图的层次全部贯穿;否则视图层次的分支是被否定的。你不太需要调用这个方法,但是你需要重写它用来隐藏子视图的触摸事件。         ...hitTest:withEvent:方法的处理流程如下:     • 首先调用当前视图的pointInside:withEvent:方法判断触摸点是否在当前视图内;     • 若返回NO,则hitTest...:withEvent:返回nil;     • 若返回YES,则向当前视图的所有子视图(subviews)发送hitTest:withEvent:消息,所有子视图的遍历顺序是从top到bottom,即从...subviews数组的末尾向前遍历,直到有子视图返回非空对象或者全部子视图遍历完毕;     • 若第一次有子视图返回非空对象,则hitTest:withEvent:方法返回此对象,处理结束;

70830
  • 史上最详细的iOS之事件的传递和响应机制-原理篇

    ,系统会销毁相应的UITouch对象 提 示:iPhone开发中,要避免使用双击事件!...注 意:如果hitTest:withEvent:方法中返回nil,那么调用该方法的控件本身和其子控件都不是最合适的view,也就是在自己身上没有找到更合适的view。...所以事件的传递顺序是这样的:   产生触摸事件->UIApplication事件队列->[UIWindow hitTest:withEvent:]->返回更合适的view->[子控件 hitTest:...这就导致了返回的不是自己而是触摸点真正所在的view。所以还是建议在父控件的hitTest:withEvent:中返回子控件作为最合适的view!...首先看initial view能否处理这个事件,如果不能则会将事件传递给其上级视图(inital view的superView);如果上级视图仍然无法处理则会继续往上传递;一直传递到视图控制器view

    11.4K70

    iOS中的事件的产生和传递

    2.3如何寻找最合适的view 两个重要的方法: hitTest:withEvent:方法 pointInside方法 2.4 hitTest:withEvent:方法什么时候调用 只要事件传递给一个控件...,控件就会调用自己的hitTest:withEvent:方法 注 意:不管控件能不能处理事件,也不管触摸点在不在这个控件上,事件都会先传递给这个控件,随后再调用hitTest:withEvent:方法...2.5拦截事件的处理 ●不管点击哪里,最合适的view都是hitTest:withEvent:方法中返回的那个view。...注 意:如果hitTest:withEvent:方法中返回nil,那么调用该方法的控件本身和其子控件都不是最合适的view,也就是在自己身上没有找到更合适的view。...2.在视图层次结构的最顶级视图,如果也不能处理收到的事件或消息,则其将事件或消息传递给window对象进行处理 3.如果window对象也不处理,则其将事件或消息传递给UIApplication对象

    91210

    在一个app中间有一个button,在你手触摸屏幕点击后,到这个button收到点击事件,中间发生了什么

    设备将touch到的UITouch和UIEvent对象打包, 放到当前活动的Application的事件队列中 单例的UIApplication会从事件队列中取出触摸事件并传递给单例UIWindow UIWindow...使用hitTest:withEvent:方法查找touch操作的所在的视图view hitTest:withEvent是如何找到对应的View?...1.首先调用当前视图的pointInside:withEvent:方法判断触摸点是否在当前视图内; 2.若返回NO,则hitTest:withEvent:返回nil; 3.若返回YES,则向当前视图的所有子视图发送...hitTest:withEvent:消息,(所有子视图的遍历顺序是从top到bottom,即从subviews数组 的末尾向前遍历,直到有子视图返回非空对象或者全部子视图遍历完毕); 4.若第一次有子视图返回非空对象...,则hitTest:withEvent:方法返回此对象,处理结束; 5.如所有子视图都返回非,则hitTest:withEvent:方法返回自身(self)。

    1.1K10

    iOS 小技能: Responder Chain(响应者链)【下篇】

    (keyWindow) 主窗口会在视图层次结构中找到一个最合适的视图来处理触摸事件,但是这仅仅是整个事件处理过程的第一步 找到合适的视图控件后,就会调用视图控件的touches方法来作具体的事件处理 touchesBegan...II 响应者链的事件传递过程 1).如果view的控制器存在,就传递给控制器;如果控制器不存在,则将其传递给它的父视图 2).在视图层次结构的最顶级视图,如果也不能处理收到的事件或消息,则其将事件或消息传递给...2.1 触摸事件处理的详细过程 用户点击屏幕后产生的一个触摸事件,经过一系列的传递过程后,会找到最合适的视图控件来处理这个事件 找到最合适的视图控件后,就会调用控件的touches方法来作具体的事件处理...接着就会调用上一个响应者的touches….方法 2.3 模拟系统的hitTest方法原理 /* hitTest : withEvent: 作用:找做合适的view;当事件传递给一个控件的时候调用...__); // [super hitTest:point withEvent:event];//使用系统默认做法 //1、判断自己能否接受事件 if (self.userInteractionEnabled

    97730

    iOS面试题:事件传递和响应机制

    主窗口会在视图层次结构中找到一个最合适的视图来处理触摸事件,这也是整个事件处理过程的第一步。 找到合适的视图控件后,就会调用视图控件的touches方法来作具体的事件处理。 2....1.首先判断主窗口(keyWindow)自己是否能接受触摸事件 2.判断触摸点是否在自己身上 3.子控件数组中从后往前遍历子控件,重复前面的两个步骤(所谓从后往前遍历子控件,就是首先查找子控件数组中最后一个元素...:(CGPoint)point withEvent:(UIEvent *)event; 3.2 hitTest:withEvent 方法介绍 什么时候调用?...只要事件一传递给一个控件,这个控件就会调用他自己的hitTest:withEvent:方法 作用 寻找并返回最合适的view(能够响应事件的那个最合适的view) 注 意 1.不管这个控件能不能处理事件...,也不管触摸点在不在这个控件上,事件都会先传递给这个控件,随后再调用hitTest:withEvent:方法 2.如果hitTest:withEvent:方法中返回nil,那么调用该方法的控件本身和其子控件都不是最合适的

    1.2K10

    UI篇-UIResponder之事件传递和响应精析

    UIView对象并不一定会把事件传递给每一个子view,因为UIView是通过hitTest方法来判断点击事件发生在哪个子view上面的,会采用逆序查询也就是优先查询后加载的子试图,这样做也是为了优化查找速度...如果它第一个hitTest就命中了的话,这个事件就不会再被传递给其他子试图了。 举个例子: ?...如果hitTest返回了对应视图则说明在当前视图层级下有最优响应视图,可能为self或者其subview,这个要看具体返回。 如何看到这一切呢?...//******************* 华丽的分割线 **************** 系统先调用pointInSide: WithEvent:判断当前视图以及这些视图的子视图是否能接收这次点击事件...我们在使用UITextView和UITextField的时候,可以通过它们的inputAccessoryView属性给输入时呼出的键盘加一个附属视图,通常是UIToolBar,用于回收键盘。

    2.5K30

    事件传递、响应者链条

    )point withEvent:(nullable UIEvent *)event; HitTest的顺序 UIApplication -> UIWindow -> Root View -> subview...UIApplication和UIWindow通过sendEvent:方法传递事件 UIWindow 之后会通过hitTest:withEvent:方法寻找触碰点所在的视图 hitTest:withEvent...:原理 // point是该视图的坐标系上的点 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { // 1.判断自己能否接收触摸事件...[self pointInside:point withEvent:event]) return nil; // 3.从后往前遍历自己的子控件,看是否有子控件更适合响应此事件 int count...在视图层次结构的最顶级视图,传递给ViewController ViewController将事件传递给window对象进行处理 window对象继续将事件或消息传递给UIApplication

    89010

    iOS 点击事件如何穿透透明的View?

    -(id)hitTest:(CGPoint)pointwithEvent:(UIEvent *)event { UIView *hitView= [super hitTest:point withEvent...:withEvent:方法的处理流程如下: 首先调用当前视图的pointInside:withEvent:方法判断触摸点是否在当前视图内; 若返回NO,则hitTest:withEvent:返回nil;...若返回YES,则向当前视图的所有子视图(subviews)发送hitTest:withEvent:消息,所有子视图的遍历顺序是从top到bottom,即从subviews数组的末尾向前遍历,直到有子视图返回非空对象或者全部子视图遍历完毕...; 若第一次有子视图返回非空对象,则hitTest:withEvent:方法返回此对象,处理结束; 如所有子视图都返回非,则hitTest:withEvent:方法返回自身(self)。...判断点在不在当前控件 if ([self pointInside:point withEvent:event] == NO) {return nil;} // 3.从后往前遍历自己的子控件

    4.1K10

    iOS开发--事件传递,响应者链条及常见面试题

    UIWindow来处理,UIWindow对象首先会使用hitTest:withEvent:方法寻找此次Touch操作初始点所在的视图(View),即需要将触摸事件传递给其处理的视图(最合适来处理的控件)...1.自己能响应触摸事件 2.触摸点在自己身上 3.从后往前递归遍历子控件, 重复上两步 4.如果没有符合条件的子控件, 那么就自己最合适处理 3.两个重要的响应方法(UIView的) 1.hit-test...view:事件传递给控件的时候, 就会调用该方法,去寻找最合适的view并返回看可以响应的view - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent...]; // 3.3判断是否在在子控件中找到了更合适的子控件(递归循环) UIView *fitView = [childView hitTest:childP withEvent...在视图层次结构的最顶级视图,如果也不能处理收到的事件或消息,则其将事件传递给window对象进行处理 3\.

    85631

    iOS事件响应控制 原

    这一步是什么意思,其实很简单,就是找到你所触摸点对应的那个最上层的视图,它的工作原理是这样的:当用户发出事件后,会产生一个触摸事件,系统会将该事件加入到一个由UIApplication管理的事件队列中,...UIApplication会取出队列中最前面的事件,发消息给UIWindow,然后UIWindow会对其所有子视图调用hitTest:withEvent:这个方法,这个方法会返回一个UIView的对象,...这个方法在执行的时候,它会调用当前视图的pointInside:withEvent:这个方法,如果触摸事件在当前视图范围内,pointInside:withEvent:会返回YES,否则会返回NO;如果返回...YES,则会遍历当前视图的所有子视图,统统发送hitTest:withEvent:这个消息,如果返回NO,则hitTest:withEvent:方法返回nil; 上面说起来有些绕,其实就是:hitTest...:withEvent:方法会一层一层的向上找,若最上层响应的子视图pointInside:withEvent:返回YES,则返回此子视图,如果所有的都返回nil,则返回当前视图本身self。

    55240

    IOS触摸事件分发机制详解

    前言 很多时候大家都不关心IOS触摸事件的分发机制的实现原理,当遇到以下几种情形的时候你很可能抓破头皮都找不到解决方案: 某个点击消息由父视图来处理,子视图怎么把消息传递给父视图 这个按钮不灵敏,怎么扩大点击响应区域...Hit-Testing就完美的解决了这个问题,通过检测触摸点是否在相关的视图边界范围内,如果在,就继续递归检测该视图的所有子视图,离用户最近的那个视图的边界如果包含触摸点,那么它就是我们要找的Hit-Test...point是否在view的边界范围内,如果在view的边界范围内,则返回YES,然后,在子视图中递归调用 hitTest:withEvent: 。...如果不在范围内,则返回NO,那么它的所有子视图都会被忽略,hitTest:withEvent:返回 nil 。...解决办法通常有两种: 父视图和子视图都重写- (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event

    3.6K90

    iOS-UITouch事件处理详解1. iOS中的事件基本介绍2.UITouch3.UIEvent4. 事件的产生和传递5. 通过UITouch方法监听View的触摸事件的缺点

    从后往前遍历子控件,重复前面的两个步骤 如果没有符合条件的子控件,那么就自己最适合处理 注意:如果父控件不能接收触摸事件,那么子控件就不可能接收到触摸事件 UIView中提供了两个方法用来寻找最合适的...// 用来寻找最合适的View处理事件,只要一个事件传递给一个控件就会调用控件的hitTest方法,参数point 表示方法调用者坐标系上的点 - (nullable UIView *)hitTest:...默认就是NO,因此UIImageView以及它的子控件默认是不能接收触摸事件的。...如果控制器不存在,其父视图为上一个响应者,将其传递给它的父视图 在视图层次结构的最顶级视图,如果也不能处理收到的事件或消息,则其将事件或消息传递给window对象进行处理 如果window对象也不处理,...因此iOS3.2之后我们在日常开发中关于触摸事件处理方面一般使用手势识别功能Gesture Recognizer,简化开发难度。

    1.7K60

    史上最详细的iOS之事件的传递和响应机制-实践篇

    本篇文章主要介绍如何利用事件处理的这些机制来处理公司开发中一些比较棘手的需求。例如,点击的是A视图,却要让B视图处理事件;点击子视图,却要让父视图处理事件等等。...红色的view是绿色view的父视图,白色的view又是红色view的父视图。如下要求: 需求情景一 当子控件和父控件重叠时,点击子控件,子控件响应事件。...注意,不能够重写父控件的hitTest:withEvent:方法,也就是不能够重写红色的view的hitTest:withEvent:方法。...红色的view作为父控件都没有接收到这个事件,当然他的子控件绿色的view也肯定接收不到这个触摸事件。...] || [self.subviews[0] pointInside:greenViewPoint withEvent:event]) { // 触摸点在自己身上或者在子控件身上都返回自己作为最合适的view

    8.5K20

    iOS-控件响应用户控制事件之事件处理

    2.UIApplication会从事件队列中取出最前面的事件,并将事件分发下去以便处理,通常,先发送事件给应用程序的主窗口(keyWindow) 3.主窗口会在视图层次结构中找到一个最合适的视图来处理触摸事件...,这也是整个事件处理过程的第一步 4.找到合适的视图控件后,就会调用视图控件的touches方法来作具体的事件处理 touchesBegan… touchesMoved… touchedEnded… 如果父控件不能接收触摸事件...从后往前遍历子控件,重复前面的两个步骤 如果没有符合条件的子控件,那么就自己最适合处理 原理 // point:是方法调用者坐标系上的触摸点的位置 - (UIView *)hitTest:(CGPoint...UIView *fitView = [childView hitTest:childP withEvent:event]; if (fitView) { return...,如果也不能处理收到的事件或消息,则其将事件或消息传递给window对象进行处理 如果window对象也不处理,则其将事件或消息传递给UIApplication对象 如果UIApplication也不能处理该事件或消息

    97670

    iOS 小技能: Responder Chain(响应者链)【上篇】

    当手指离开屏幕时,系统会销毁相应的UITouch对象 提示:iPhone开发中,要避免使用双击事件!...一个事件响应者的完成主要经过两个过程:hitTest方法命中视图和响应者链确定响应者。...hitTest方法首先从顶部UIApplication往下调用(从父类到子类),直到找到命中者,然后从命中者视图沿着响应者链往上传递寻找真正的响应者。...4.1.命中测试 命中测试(hitTest)主要会用到视图类的hitTest函数和pointInside函数。...命中检测具体迭代的过程为:如果触摸点在当前视图内,那么递归对当前视图内部所有的子视图进行命中检测;如果不在当前视图内,那么返回NO停止迭代。这样最终会确定屏幕上最顶部的命中的视图元素,即命中者。

    1.1K30

    iOS 事件体系知识及原理小记

    执行hitTest:withEvent:; 如果subView的hitTest:withEvent:有返回,则返回该返回; 如果subView的hitTest...(UIWindow); 主窗口会调用hitTest:withEvent:方法在视图(UIView)层次结构中找到一个最合适的UIView来处理触摸事件,并将UITouch与UIEvent交给UIView...UIWindow开始,然后一层层子view查找下去,最终view 2会作为最合适的响应者被hitTest返回,因为view 2满足了两个条件: 通过hitTest找到了view 2 view 2内部没有其他子...再看看另一个特殊的场景: view 2还是view 1的子view;但当一个点击落在view 2的区域内时,查找还是从UIWindow开始,但在view 1的hitTest中就返回了nil,因为点击区域不在...view 1中,导致view 1的子view都不会再进行hitTest;这点跟web中的事件处理是截然不同的;这也导致一些超边界的点击必须由业务去重载hitText方法。

    1.3K90
    领券