Summary of Hit-test usage: How to prevent touch events from being passed to a child view

Source: Internet
Author: User

Today, someone in the group asked the question: How to prevent touch events from passing to a child view after adding a "feel" event. Actually read the official document event handling Guide for iOS child shoes, should be no problem. But I'll just summarize it.

After the touch, the main steps are as follows:

(1), event distribution: How to determine which view the currently clicked Point is handled by. Hit-test to determine Hit-view (2), event response: How to handle an event after determining Hit-view.

When Hit-view is identified, the first responder is the current Hit-view, and then the touch event is handled according to the responder chain.

Hand gestures to the first processing gestures, gesture recognition failed, perform touch series callback processing.


Scenario ApplicationQuestion 1: If the parent view userinteractionenable is no, then the child view can receive the touch event. Analysis: Because the parent view returns nil when hit-testing, it is not possible to turn the child view to hit-testing. This is why the button cannot respond when the UIButton is loaded on Imgview
Question 2: If a view a (a above is loaded with gesture processing) is covered by View B, A and B are all views of view X, then how do I get a gesture to respond.   Analysis: Because B covered a, so the results of the hit-test, Hit-view must be b,a gestures can not respond to this: 1, set b.userinteractionenable = NO;   2, B.hidden = YES; 3, B.alpha = 0; In each of the 3 cases, a can respond to gestures. Because of this setting, in the hit-testing, the B-View HitTest method returns the nil, the final hit-view is a, so the touch event turns to a to handle.
Question 3: If a Viewa does not want its subview to handle the touch event, it does it by itself. Analysis: Viewa do not want to touch the event passed to its subview, that is, Viewa itself to block the transfer of touch events, as long as the end of the touch after the Hit-view is his own can be. For example, the subview of Viewa for YLVIEWSUB1 has the following 2 methods: Method One: It is not recommended to overload HitTest in Viewa. m files (Note: Viewa is a custom UIView to overload this method), as follows-(UIView *) HitTest: ( Cgpoint) point withevent: ( Uievent *) Event
{UIView *hitview = [Super Hittest:point withevent:event]; At this point Hitview is the hit-view that has been detected, is self or subviews (hitted subview)
/* Note:
* If you want to block touch events from passing to Subview, the following 2 approaches are not reasonable:
/* Method 1: * Regardless of the 3721 direct return self is also wrong, because when not clicked on self (including its subview), self becomes hit-view
*/
return self; /* Method 2: * Because Hitview may return the subview of its subview subview ...
* So I can't do this. If you can determine that self's subview is only one level, it's OK to do so.
*/
if (hitview. Superview = = Self && hitview = self) {
return self; Click on its subview also by its own to handle, Subview is never Hit-view (will never be the first responder, do not handle touch)
/* The correct approach: The following method two, overloaded HitTest * 1 in Subview, can overload the HitTest method in the self's Subview and return directly to nil, then click on Self's Subview The last Hit-view or self?
* So when overloading this method, be sure to make sure of the specific application scenario.
*/

return nil; You can see that overloading is not a good implementation directly in Viewa, and if Viewa is a vc.view, then there is no way to overload the HitTest method.
Method Two: It is recommended to overload the HitTest in the class of Viewa Subview (YLVIEWSUB1), in YLViewSub1 's. m file,-(ID) HitTest: ( Cgpoint) point withevent: ( Uievent *) Event
{
UIView *hitview = [Super Hittest:point withevent:event];
if (Hitview = self) {
return nil;
} else {
return hitview; Someone may have a question: the above said to return directly here nil not on it, why still need to deal with the situation. In fact, this depends on the specific situation, if the YLViewSub1 above there are subview, direct return to nil, then will be ignored, so if you want to ignore all the direct return to nil, otherwise it can be treated like this. In addition, there is a simpler way to directly let Viewa subview userinteraction as no, then Subview will not be touched by the message.
Extension: Hit-test There is another scene, such as Viewa has b,c two subview, but they have the overlap of 2 parts, click on the overlap, that how to specify the B response or C to respond. Analysis: By default, when Hit-test, is the subviews from the top of the Subview start to execute hit-test, that is, if the first plus B, then load C, then Hit-test is first C first B, so click on the overlap part, that is C is Hit-view, Then the C response. How to make B respond first. -(UIView *) HitTest: ( Cgpoint) point withevent: ( Uievent *) Event
{
UIView *hitview = [Super Hittest:point withevent:event]; if (Hitview = = VIEWC) {//click on C, let Hit-view be B, then B is the first responder return VIEWB;
} else {
return hitview;
In this way, when the click of the overlap part of the response by B, click B,c not coincide with their respective response.
Question 4: If a view is not willing to handle the touch event, but want its subviews to deal with, how to do. Scenario: This is a bit of a problem, because by default it's Subview to deal with, where is the application scenario? It may be that if you click View yourself and let his parent view handle it, clicking on the view above Subview by the Subview response is more reasonable. Analysis: Set view.userinteractionenable = NO; After that, although it does not respond to the touch event, its child view will not respond, so you cannot do so. This is the time to use HitTest to process,-(UIView *) HitTest: ( Cgpoint) point withevent: (     Uievent *) Event {UIView *hitview = [Super HitTest:p oint withevent:event]; if (Hitview = self) {return nil;//is self, does not do processing, it is handled by its parent view} else {
return hitview; When it's subview, it's handled by Subview.
}
}
Question 5: What if a view itself does not want to deal with it and is unwilling to pass it on to its responder chain for others to handle? Analysis: First of all, to determine the processing of objects must be their own, and then, in their own processing when discarded, that is, their own overload response function, and then the response function inside do not do anything, so will not continue to pass up, that is, in their own here to do an empty processing to the response
Question 6: A full-screen UIView loaded with tap gestures, loading a uitableview on this view, and clicking on the cell did not perform TableView didselected: method, but responded to _ontap gestures and how to handle them. Workaround:-(BOOL) Gesturerecognizer: (Uigesturerecognizer *) Gesturerecognizer Shouldreceivetouch: (Uitouch *) touch
{
Tianyi Memo:
When clicked on the TableView, because TableView does not respond to tap, it will give its parent view self to respond, that is, response _ontap: But that's not what we want.
We need to click

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.