• 消息点击事件的响应链---hitTest:withEvent:方法


    *当用户点击屏幕时,会产生一个触摸事件,系统会将触摸事件加入到 UIApplication管理事件队里中

    *UIApplication 会从事件队列中取出最前面的事件进行分发以便处理,通常,先发送事件给应用程序主窗口(UIwindow0

    *主窗口会调用 hitTest:withEvent:方法在视图(UIView)层次结构中找到一个最合适的 UIView来处理触摸事件

    (hitTest:LwithEvent:其实是 UIView 的一个方法UIWindow 继承自 UIView,因此主窗口UIWinow 也是属于视图的一种)

    hitTest:withEvent:处理流程大致是这样的:

    首先调用当前视图的 pointInside:withEvent:方法判断触摸点是否在当前视图内:

    若 pointInside:withEvent:返回 NO, 说明触摸点不在当前视图内,,则当前的 hitTest:withEvent:返回 nil

    若 pointInside:withEvent: 返回 YES, 说明触摸点在当前视图内,则遍历其所有子视图(subviews),调用子视图的 hitTest:withEvent: 方法重复前面的步骤,子视图遍历的顺序是从 top 到 bottom, 即从 subviews 数组的末尾向前遍历,直到有子视图的 hitTest:withEvent: 方法返回非空对象或者全部子视图遍历完毕

    ▷ 若第一次有子视图的hitTest:withEvent:方法返回非空对象,则当前视图的hitTest:withEvent:方法就返回此对象,处理结束

    ▷ 若所有子视图的hitTest:withEvent:方法都返回nil,则当前视图的hitTest:withEvent:方法返回当前视图自身(self)

    • 最终,这个触摸事件交给主窗口的hitTest:withEvent:方法返回的视图对象去处理

    我大致画了个iOS触摸事件分发的原理图:

    • hitTest:withEvent:方法会忽略以下视图:

    1> 隐藏(hidden=YES)的视图

    2> 禁止用户操作(userInteractionEnabled=NO)的视图

    3> alpha<0.01的视图

    4> 如果一个子视图的区域超过父视图的区域(如果父视图的clipsToBounds属性为NO,超过父视图区域的子视图内容也会显示),那么正常情况下在父 视图区域外的触摸操作不会被识别,因为父视图的pointInside:withEvent:方法会返回NO,这样就不会继续向下遍历子视图了。当然,也 可以重写pointInside:withEvent:方法来处理这种

        引自http://www.cnblogs.com/mjios/archive/2013/03/06/2945347.html

    风吹起的地方不是因为风动,是因为心动
  • 相关阅读:
    Azure 虚拟机安全加固整理
    AzureARM 使用 powershell 扩容系统磁盘大小
    Azure Linux 云主机使用Root超级用户登录
    Open edX 配置 O365 SMTP
    powershell 根据错误GUID查寻错误详情
    azure 创建redhat镜像帮助
    Azure Powershell blob中指定的vhd创建虚拟机
    Azure Powershell 获取可用镜像 PublisherName,Offer,Skus,Version
    Power BI 连接到 Azure 账单,自动生成报表,可刷新
    Azure powershell 获取 vmSize 可用列表的命令
  • 原文地址:https://www.cnblogs.com/GLbog/p/4992820.html
Copyright © 2020-2023  润新知