• 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

  • 相关阅读:
    主流NoSQL数据库评测之HBase
    Java Io原理及应用
    Facebook:HBase每月存储1350亿条信息
    Facebook为何选择云计算开源Hadoop
    ActiveMq配置解析
    主流NoSQL数据库评测之HandlerSocket
    软件类官方网站收藏
    Mongodb 更新失败解决方案
    主流NoSQL数据库全方位评测:MongoDB
    java为什么比c++要慢?以及如何提高java的效率
  • 原文地址:https://www.cnblogs.com/widgetbox/p/lm.html
Copyright © 2020-2023  润新知