I. Classification of events
For iOS device users, there are three main ways to manipulate devices: Touch the screen, shake the device, and control the device through a remote controlled facility. The following three types of events are available:
1. Touchscreen events (Touch event)
2, motion events (motion event)
3. Remote Control Events (Remote-control event)
Today, as an example of touch event, the process of handling events in the Cocoa Touch framework is illustrated. First we have to introduce the concept of the responder chain:
Second, the responder chain (Responder Chain)
First, the responder objects (Responder object), as the name implies, refer to objects that have the ability to respond and handle events. A responder chain is a hierarchical structure of a series of responder objects.
Uiresponder is the base class for all response objects, and the interfaces that handle each of these events are defined in the Uiresponder class. The familiar uiapplication, Uiviewcontroller, UIWindow, and all Uikit classes that inherit from UIView are inherited directly or indirectly from Uiresponder, so their instances are the responder objects that can form the responder chain. Figure one shows the basic composition of the responder chain:
Figure A
As can be seen from figure I, the responder chain has the following characteristics:
1, the responder chain is usually composed of a view (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 View controller (if any) the next responder is the parent view of the view it manages;
4. The content view of the Singleton window (UIWindow) will point to the window itself as its next responder
It should be noted that the Cocoa touch app is not like the Cocoa application, it has only one UIWindow object, so the entire responder chain is a little 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 loop.
Iii. Distribution of events (event Delivery)
First responder refers to the current responder object (usually a UIView object) that accepts the touch, meaning that the object is currently interacting with the user, which is the beginning of the responder chain. The mission of the entire responder chain and event distribution is to find the first responder.
The UIWindow object sends the event as a message to the first responder, giving it an opportunity to handle the event first. If the first responder does not process, the system passes the event (through the message) to the next responder in the responder chain to see if it can be processed.
When the iOS system detects a finger touch, it packs it into a Uievent object and puts it into the event queue of the currently active application. The uiapplication of a singleton takes a touch event from the event queue and passes it to the uiwindow of the Singleton, UIWindow object first uses the Hittest:withevent: method to find the view that contains the initial point of the touch operation, That is, you need to pass the touch event to its processed view, which is called Hit-test view.
The UIWindow instance object first calls Hittest:withevent on its content view: This method calls Pointinside:withevent on each view in its view hierarchy: (This method is used to determine if the location of the click event is in the current view, to see if the user clicked the current view), and if pointinside:withevent: return yes, continue to cascade until you find where the touch operation occurred, This is the Hit-test view you are looking for.
Hittest:withevent: The process of the method is as follows:
First call the current view's Pointinside:withevent: method to determine whether the touch point is within the current view;
If no is returned, hittest:withevent: returns nil;
If yes, the Hittest:withevent: message is sent to all the child views of the current view (Subviews), and all child views are traversed in the order from the topmost view to the bottom view, which is the forward traversal from the end of the subviews array. Until a child view returns a non-empty object or all the child views are traversed;
If the child view returns a non-empty object for the first time, the Hittest:withevent: method returns this object, processing ends;
If all child views return non, the Hittest:withevent: method returns itself (self).
Figure II
Join the user click on the view E, the following together with the Diagram II Hit-test view of the process:
1, A is the root view of UIWindow, therefore, the Uiwindwo object will be the prime minister of a hit-test;
2, obviously the user clicks the scope is within the range of a, therefore, pointinside:withevent: Returns the Yes, then will continue to check A's child view;
3. At this time there will be two branches, B and C:
The clicked range is no longer within B, so the pointinside:withevent of the B branch: Return no, corresponding to the hittest:withevent: return nil;
Click on the range in C, that is, C pointinside:withevent: return yes;
4. There are two branches of D and E:
The clicked Range is no longer in D, so the pointinside:withevent of D: Return no, corresponding to the hittest:withevent: return nil;
The clicked Range is within E, that is, E's pointinside:withevent: Returns Yes, since E has no child view (which can also be understood as hit-test when the sub-view of E is returned to nil), therefore, E's hittest:withevent: will return E, Back again, that is the hittest:withevent of C: return e--->>a hittest:withevent: return E.
At this point, the first responder of this click event is successfully found through the event distribution logic of the responder chain.
It is not difficult to see that this process is a bit like the idea of binary search, so that the fastest speed, the most accurate positioning can respond to touch events UIView.
Third, the description
1. If the final hit-test does not find the first responder, or if the first responder does not handle the event, the event will go up backwards along the responder chain, and the event will be discarded if neither the UIWindow instance nor the UIApplication instance can handle the event;
2. Hittest:withevent: The method ignores the view that hides (Hidden=yes), disables user action (Userinteractionenabled=yes), and the alpha level is less than 0.01 (alpha< 0.01) of the view. If the area of a child view exceeds the bound area of the parent view (the Clipstobounds property of the parent view is no, so that the child view content of the parent view's bound area is also displayed), the touch operations of the child view outside the parent view will normally not be recognized. Because the parent view's Pointinside:withevent: Method returns no, it does not continue to traverse the child view down. Of course, you can also override the Pointinside:withevent: method to handle this situation.
3, we can rewrite hittest:withevent: to achieve certain purposes, the following link is an interesting application example, of course, in practical applications rarely used.
http://download.csdn.net/detail/wzzvictory_tjsd/5716299
Reference Documentation:
https://developer.apple.com/library/ios/#documentation/eventhandling/conceptual/eventhandlingiphoneos/event_ Delivery_responder_chain/event_delivery_responder_chain.html#//apple_ref/doc/uid/tp40009541-ch4-sw1
Cocoa Touch Event Processing Flow--responder chain