美文网首页
触摸事件的传递和响应机制

触摸事件的传递和响应机制

作者: springerPrivate | 来源:发表于2023-05-26 22:40 被阅读0次

    从用户触摸屏幕到app的响应过程。

    过程

    事件的产生及分发

    • 点击屏幕会产生一个触摸事件。
    • 主线程的runloop会接收到该事件并将其存放到消息队列中。
    • UIApplication 会从消息队列中取事件并将事件分发给window。

    找寻合适的视图

    在寻找合适视图的过程中,主要会用到UIView的两个方法:- (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event;以及- (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event;
    hitTest方法中会对视图进行一定的判断:比如 userInteractionEnabled 、isHidden 、alpha 是否>=0.01,如果视图可交互,非隐藏,透明度比0.01大,就会调用pointInside方法判定事件的触发点是否在视图区域内,否则hitTest会返回nil。

    • 事件被分发到window,事件就开始在视图树中传递,寻找合适的视图。
    • 视图会调用hitTest方法,在hitTest方法中会调用pointInside方法,若pointInside返回NO,hitTest返回nil。如果pointInside返回YES,则判断该视图是否有子视图。
    • 如果没有子视图,该视图的hitTest会返回该视图。如果有子视图,会倒序遍历子视图,子视图会调用hitTest。
    • 如果所有的子视图的hitTest都返回nil,则该视图的hitTest返回该视图。
    • 若第一次有hitTest返回非空的视图对象。则递归返回该视图,该视图就是最合适的视图。
    • 如果最终没有找到合适的视图,window会将事件返还给UIApplication,系统会忽略掉此事件。

    事件的响应

    • 找到合适的响应者后,事件的响应链已确定。
    • 首先判断响应者是否能响应此事件。如果可以响应,则响应事件。
    • 如果不能响应,则会沿着响应链来寻找响应者。如果最终没有找到能响应的响应者,则系统会忽略掉此事件。

    响应链的构建情况:

    • view:如果view是被UIViewController对象管理,view的下一个响应者就是UIViewController;如果不是被UIViewController对象管理的,下一个响应者就是superview。
    • UIViewController:同返回它管理的view的superview。
    • UIWindow:返回application对象。
    • UIApplication:返回给应用委托AppDelegate。

    注意点儿

    一次触摸事件,触发两次hitTest:

    • uiview(geometry) _hitTest:withEvent:windowServerHitTestWindow:
    • __updateTouchesWithDigitizerEventAndDeterminelfShouldSend_block_invoke

    UIControl 和 UIButton ,会影响事件的响应。
    如果能响应事件,则响应事件。若不能响应,会截断事件的响应。

    UIGestureRecognizer 和 UITextField ,会影响事件响应。
    若能响应事件,会将触摸取消。若不能响应,会拦截事件的响应。

    UIGestureRecognizer是一个基于NSObject的类,它能影响事件的响应,是因为它会被添加到一个View上。

    UITextField ,UIButton 是基于UIControl的类, UIControl 是基于UIview的。
    UIApplication 和 UIViewController 是基于 UIResponder的类。

    应用

    根据事件的传递和响应机制,我们可以在事件传递和响应过程中做操作,以改变原有的事件响应。

    • 事件透传
    • 改变响应区域

    相关文章

      网友评论

          本文标题:触摸事件的传递和响应机制

          本文链接:https://www.haomeiwen.com/subject/stlledtx.html