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