"Original" iOS touch event depth Resolution

Source: Internet
Author: User

Overview

This article mainly analyzes the entire processing mechanism from the touch of our fingers to the Apple device to the final response event. Essentially, the entire process can be divided into two steps:

Step 1: Find the target. Find the final recipient of the touch event in the iOS view hierarchy;

Step 2: Incident response. Handle touch events based on the iOS responder chain (Responder Chain)

looking for a target

The two great weapons used in the search for the target phase are uiview. hittest:withevent: as well pointinside:withevent: method. The process of finding a target is also known as hit-testing. Let's take a look at a picture (note: The figure from MJ) is more intuitive:

The following explains the principle of processing:

1, the finger touch the screen, this action is packaged into a Uievent object sent to the current active uiapplication (active application), application the event object to the end of the task queue to wait for processing (FIFO, First-come first processing);

2. UIApplication A single case sends an event to the app's main window (all the displayed view is added to the window);

3. The main window invokes the view hierarchy using Hit-testing to confirm the final response target, also known as hittesting view.

In the absence of any overloaded operation, the system default hit-testing processing mechanism is as follows:

The current view invokes its own Pointinside:withevent: method to determine whether the touch point is within its own range:

    • If the Pointinside:withevent: method returns no, the touch point is not in its own range, then the current view's Hittest:withevent: method returns nil, and all subview on the current view are not judged. A bit of leadership of the opinion of a vote veto the taste.
    • If the Pointinside:withevent: method returns Yes, the touch point is within its own range. But it is impossible to judge whether in oneself or in subview. At this point, all subviews are traversed, and the HitTest method is called for each subview. It is important to note that the order of traversal begins at the end of the subviews array of the current view. As a result, the Subview from the user's nearest upper layer will be called the HitTest method first.
    • Once the HitTest method returns a non-empty view, the returned view is the view of the final corresponding touch event, looking for the phase of the hittesting view to end and no longer traverse.
    • If all Subviews hittest methods for the current view return nil, the current view's HitTest method returns self as the final hittesting view, processing ends.

This is the first stage to look for a response to the view mechanism. Here we will combine a specific example again (picture quoted from the tech blog):

The following hit-testing occur when the user clicks on the viewd area:

    • Viewa's pointinside returns Yes, because the touch point is within its bounds. Traverse Viewa of two subview;
    • VIEWB's Pointinside returns no because the touch point is not within its bounds, and Viewb's HitTest method returns nil. And a vote of veto, all subviews on the VIEWB will no longer be hit-testing dealt with. VIEWC's pointinside returns Yes, because the touch point is within its bounds range, VIEWC's HitTest method returns the default processing, which is return [Super Hittest:point Withevent:event]; Traverse VIEWC of two subview;
    • VIEWD's pointinside returns yes because the touch point is within its bounds range, and viewd has no subview, so the HitTest method returns itself. Hittesting view found, end processing.

Here are a few things to emphasize:

1, HitTest method call Pointinside method;

2, hit-testing process is from Superview to Subview step by step, that is, from the root node of the hierarchical tree to the leaf node transmission;

3. When the following settings are encountered, the pointinside of view will return the No,hittest method to return nil:

    • View.ishidden=yes;
    • view.alpah<=0.01;
    • View.userinterfaceenable=no;
    • Control.enable=no; (Uicontrol's properties)

The hit-testing process can be described in the following code:

-(UIView *) HitTest: (cgpoint) point withevent: (Uievent *) Event {    if (self.alpha <= 0.01 | |!) self.userinteractionenabled | | Self.hidden) {        return nil;    }    BOOL inside = [self pointinside:point withevent:event];    UIView *hitview = nil;    if (inside) {        nsenumerator *enumerator = [Self.subviews reverseobjectenumerator];        For (UIView *subview in enumerator) {            Hitview = [Subview hittest:point withevent:event];            if (Hitview) {break                ;            }        }        if (!hitview) {            hitview = self;        }        return hitview;    } else {        return nil;    }}

  

Incident Response

The last part we found hittesting view through the hit-testing mechanism, the hittesting view is the responder responder of the touch event. In an iOS system, an object capable of responding to and handling events is called Responder object, and Uiresponder is the topmost base class for all responder. When hittesting view finishes its own action, it can pass the message to the next level of responder as needed. What would the next level of responders be? This depends on the responder chain responder Chain in iOS, as shown in:

    • The Nextresponder property of the UIView, if there is a Uiviewcontroller object that manages this view, is the Uiviewcontroller object; otherwise Nextresponder is its superview.
    • The Nextresponder property of Uiviewcontroller is the Superview for which the view is managed.
    • The Nextresponder property of the UIWindow is the UIApplication object.
    • The Nextresponder attribute of the uiapplication is nil.

More specifically:

    1. If Hit-test view or first responder does not handle this event, the event is passed to its nextresponder processing, and if a Uiviewcontroller object is passed to Uiviewcontroller, Passed to its superview.
    2. If the view's viewcontroller also does not handle the event, Viewcontroller passes the event to its superview that manages the view.
    3. The top level of the view hierarchy is the UIWindow object, and if window still does not handle this event, it is passed to uiapplication.
    4. If the UIApplication object does not handle this event, the event is discarded.

Understanding the responder chain there are times when you can help me solve some practical problems. I give an example, we know that when provided to you a viewcontroller you can easily get to its view, a code of things:

viewwanted = Someviewcontroller.view;

But what if the reverse? When give you a view, let you find its viewcontroller? This time the responder chain can be helpful, the code is as follows:

@implementation UIView (Findcontroller)-(uiviewcontroller*) parentcontroller{    uiresponder *responder = [self Nextresponder];    while (responder) {if ([Responder Iskindofclass:[uiviewcontroller class]]) {return (uiviewcontroller*) responder;} responder = [responder Nextresponder];    }    return nil;} @end
written in the last

This article resolves the mechanism by which iOS responds to touch events.  You may not be able to find the application point of this knowledge now, but once you understand it, it can help you achieve some special needs, such as clicking on a button, responding to another button, and penetrating a view click to view ... What's more, you can use the above knowledge to solve irregular area touch problems (see my previous article), do not add any view to expand the touch area of the control and so on. Unrestrained, let me soar!

=======================================================

Original article, reproduced please indicate the program small Weng @ Blog Park, mail [email protected], welcome you and I in the c/c++/objective-c/machine vision and other fields to start communication!

Please jump to my GitHub homepage and follow my open source code. You are also welcome to star/fork/watch my project.

=======================================================

"Original" iOS touch event depth Resolution

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.