iOS Hierarchy and Responder Chain Analysis

The classification of events

For IOS device users, there are three main ways they operate the device: touch the screen, shake the device, and control the device through the remote control facility. The corresponding event types are as follows:

1. Touch Event

2. Motion Event

3. Remote-Control Event

Today we take Touch Event as an example to illustrate the event processing flow in the Cocoa Touch framework. First of all, we have to introduce the concept of responder chain:

 

file:///Users/meq/Desktop/screenshot%202016-06-03%20AM 11.57.34.png

2. Responder Chain

Let's talk about the Responder Object first, an object that has the ability to respond and handle events.

A responder chain is a hierarchy composed of a series of responder objects.

 

UIResponder is the base class of all response objects, and interfaces for handling the above events are defined in the UIResponder class. The familiar UIApplication, UIViewController, UIWindow and all UIKit classes that inherit from UIView directly or indirectly inherit from UIResponder, so their instances are responder objects that can form a responder chain. Figure 1 shows the basic composition of the responder chain:

 

 

As can be seen from Figure 1, the responder chain has the following characteristics:

1. The responder chain is usually composed of views (UIView);

2. The next responder of a view is its view controller (UIViewController) (if any), and then to its parent view (Super View);

3. The parent view of the view managed by the next responder of the view controller (if any);

4. The content view of the singleton window (UIWindow) will point to the window itself as its next responder

It should be pointed out that, unlike Cocoa applications, Cocoa Touch applications have only one UIWindow object, so the entire responder chain is simpler;

 

5. The singleton application (UIApplication) is the end point of a responder chain, and its next responder points to nil to end the entire cycle.

三、事件分发(Event Delivery)

第一响应者(First responder)指的是当前接受触摸的响应者对象(通常是一个UIView对象),即表示当前该对象正在与用户交互,它是响应者链的开端。整个响应者链和事件分发的使命都是找出第一响应者。

UIWindow对象以消息的形式将事件发送给第一响应者,使其有机会首先处理事件。如果第一响应者没有进行处理,系统就将事件(通过消息)传递给响应者链中的下一个响应者,看看它是否可以进行处理。

iOS系统检测到手指触摸(Touch)操作时会将其打包成一个UIEvent对象,并放入当前活动Application的事件队列,单例的UIApplication会从事件队列中取出触摸事件并传递给单例的UIWindow来处理,UIWindow对象首先会使用hitTest:withEvent:方法寻找此次Touch操作初始点所在的视图(View),即需要将触摸事件传递给其处理的视图,这个过程称之为hit-test view。

 

UIWindow实例对象会首先在它的内容视图上调用hitTest:withEvent:,此方法会在其视图层级结构中的每个视图上调用pointInside:withEvent:(该方法用来判断点击事件发生的位置是否处于当前视图范围内,以确定用户是不是点击了当前视图),如果pointInside:withEvent:返回YES,则继续逐级调用,直到找到touch操作发生的位置,这个视图也就是要找的hit-test view。
hitTest:withEvent:方法的处理流程如下:
首先调用当前视图的pointInside:withEvent:方法判断触摸点是否在当前视图内;
若返回NO,则hitTest:withEvent:返回nil;
若返回YES,则向当前视图的所有子视图(subviews)发送hitTest:withEvent:消息,所有子视图的遍历顺序是从最顶层视图一直到到最底层视图,即从subviews数组的末尾向前遍历,直到有子视图返回非空对象或者全部子视图遍历完毕;
若第一次有子视图返回非空对象,则hitTest:withEvent:方法返回此对象,处理结束;
如所有子视图都返回非,则hitTest:withEvent:方法返回自身(self)。

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326708233&siteId=291194637