iOS 触摸事件

377 阅读3分钟

下图来自网络:

1510019-62b6b1eec26730aa.png

先不论系统级的触摸事件如何处理,我们单从UIApplication获得触摸事件开始: 1.事件传递UIApplication->UIWindow->根控制器->自控制器->。。。->最合适的View。 2.事件响应从最合适的View开始,如果View实现了touches方法,那么View就可以处理事件了,如果没有则抛给View的父控件,父控件如果实现了touches方法就执行,不然继续抛给它的父控件,要是一直抛到UIApplication都执行不了的话,就丢弃该事件。(当某个控件可以执行该事件时,我们可以调用touches中的super方法,继续将该事件传递至父控件执行,这样就可以达到多个控件执行该事件,而不是当前控件执行完该事件就终止了)

截屏2021-09-24 上午11.55.48.png

上图点击红色区域结果:

ControllerView 进入 hitTest

ControllerView 进入 point

ControllerView 离开 point **true**

RedView 进入 hitTest

RedView 进入 point

RedView 离开 point **true**

YellowView 进入 hitTest

YellowView 进入 point

yellowView 离开 point **false**

YellowView 离开 hitTest **nil**

RedView 离开 hitTest Optional(<Touches.RedView: 0x12ef076e0; frame = (100 100; 100 100); layer = <CALayer: 0x600001f5f540>>)

ControllerView 离开 hitTest Optional(<Touches.RedView: 0x12ef076e0; frame = (100 100; 100 100); layer = <CALayer: 0x600001f5f540>>)

ControllerView 进入 hitTest

ControllerView 进入 point

ControllerView 离开 point **true**

RedView 进入 hitTest

RedView 进入 point

RedView 离开 point **true**

YellowView 进入 hitTest

YellowView 进入 point

yellowView 离开 point **false**

YellowView 离开 hitTest **nil**

RedView 离开 hitTest Optional(<Touches.RedView: 0x12ef076e0; frame = (100 100; 100 100); layer = <CALayer: 0x600001f5f540>>)

ControllerView 离开 hitTest Optional(<Touches.RedView: 0x12ef076e0; frame = (100 100; 100 100); layer = <CALayer: 0x600001f5f540>>)

DDApplication SendEvent

RedView touch

DDApplication SendEvent

点击红色和黄色相间的区域:

ControllerView 进入 hitTest

ControllerView 进入 point

ControllerView 离开 point **true**

RedView 进入 hitTest

RedView 进入 point

RedView 离开 point **true**

YellowView 进入 hitTest

YellowView 进入 point

yellowView 离开 point **true**

BlueView 进入 hitTest

BlueView 进入 point

BlueView 离开 point **false**

BlueView 离开 hitTest **nil**

YellowView 离开 hitTest Optional(<Touches.YellowView: 0x12ef07e50; frame = (50 50; 100 100); layer = <CALayer: 0x600001f5f6a0>>)

RedView 离开 hitTest Optional(<Touches.YellowView: 0x12ef07e50; frame = (50 50; 100 100); layer = <CALayer: 0x600001f5f6a0>>)

ControllerView 离开 hitTest Optional(<Touches.YellowView: 0x12ef07e50; frame = (50 50; 100 100); layer = <CALayer: 0x600001f5f6a0>>)

ControllerView 进入 hitTest

ControllerView 进入 point

ControllerView 离开 point **true**

RedView 进入 hitTest

RedView 进入 point

RedView 离开 point **true**

YellowView 进入 hitTest

YellowView 进入 point

yellowView 离开 point **true**

BlueView 进入 hitTest

BlueView 进入 point

BlueView 离开 point **false**

BlueView 离开 hitTest **nil**

YellowView 离开 hitTest Optional(<Touches.YellowView: 0x12ef07e50; frame = (50 50; 100 100); layer = <CALayer: 0x600001f5f6a0>>)

RedView 离开 hitTest Optional(<Touches.YellowView: 0x12ef07e50; frame = (50 50; 100 100); layer = <CALayer: 0x600001f5f6a0>>)

ControllerView 离开 hitTest Optional(<Touches.YellowView: 0x12ef07e50; frame = (50 50; 100 100); layer = <CALayer: 0x600001f5f6a0>>)

DDApplication SendEvent

yellowView touch

DDApplication SendEvent

点击黄色独立于红色之外的区域:

ControllerView 进入 hitTest

ControllerView 进入 point

ControllerView 离开 point **true**

RedView 进入 hitTest

RedView 进入 point

RedView 离开 point **false**

RedView 离开 hitTest **nil**

ControllerView 离开 hitTest Optional(<Touches.ControllerView: 0x12ef08530; frame = (0 0; 428 926); autoresize = W+H; layer = <CALayer: 0x600001f5f800>>)

ControllerView 进入 hitTest

ControllerView 进入 point

ControllerView 离开 point **true**

RedView 进入 hitTest

RedView 进入 point

RedView 离开 point **false**

RedView 离开 hitTest **nil**

ControllerView 离开 hitTest Optional(<Touches.ControllerView: 0x12ef08530; frame = (0 0; 428 926); autoresize = W+H; layer = <CALayer: 0x600001f5f800>>)

DDApplication SendEvent

ControllerView touch

DDApplication SendEvent

点击蓝色区域:

ControllerView 进入 hitTest

ControllerView 进入 point

ControllerView 离开 point **true**

RedView 进入 hitTest

RedView 进入 point

RedView 离开 point **false**

RedView 离开 hitTest **nil**

ControllerView 离开 hitTest Optional(<Touches.ControllerView: 0x12ef08530; frame = (0 0; 428 926); autoresize = W+H; layer = <CALayer: 0x600001f5f800>>)

ControllerView 进入 hitTest

ControllerView 进入 point

ControllerView 离开 point **true**

RedView 进入 hitTest

RedView 进入 point

RedView 离开 point **false**

RedView 离开 hitTest **nil**

ControllerView 离开 hitTest Optional(<Touches.ControllerView: 0x12ef08530; frame = (0 0; 428 926); autoresize = W+H; layer = <CALayer: 0x600001f5f800>>)

DDApplication SendEvent

ControllerView touch

DDApplication SendEvent

观察打印的结论:当所有合适(包含触摸点)的view都实现touches方法的时候,执行该事件的是事件传递最末端的且合适的view,当最末端且合适的view没有实现touches方法时,事件会被抛给它的父控件,以此类推,知道UIApplication。