Handling iOS users' click events

Source: Internet
Author: User

Handling iOS users' click events
Processing Mechanism

For iOS event processing, you should first find the view that can process click events, and then process the click event in the view that you find.

The processing principle is as follows:

• When a user clicks the screen, a touch event is generated, and the system adds the event to an event queue managed by UIApplication.

• UIApplication extracts the first event from the event queue for distribution for processing. Generally, the event is first sent to the application's main window (UIWindow)

• In the main window, the hitTest: withEvent: method is called to find the most suitable UIView in the UIView hierarchy to process touch events.

(HitTest: withEvent: Actually a method of UIView. UIWindow inherits from UIView, so the main window UIWindow is also a type of view)

• HitTest: withEvent: the general process is as follows:

First, call the pointInside: withEvent: Method of the current view to determine whether the touch point is in the current view:

? If pointInside: withEvent: The method returns NO, indicating that the touch point is not in the current view, the current view's hitTest: withEvent: returns nil

? If pointInside: withEvent: The method returns YES, indicating that the touch point is within the current view, the system traverses all subviews of the current view and calls the hitTest: withEvent of the subview: the method repeats the previous step. The traversal sequence of the subview is from top to bottom, that is, traversing forward from the end of the subviews array until hitTest: withEvent: the method returns non-empty objects or all sub-views:

? If a non-empty object is returned for the hitTest: withEvent: Method of the subview for the first time, the current view's hitTest: withEvent: method returns this object, and the processing is complete.

? If the hitTest: withEvent: Method of all child views returns nil, the current view's hitTest: withEvent: method returns the current view itself (self)

• Finally, the touch event is handed over to the view object returned by the hitTest: withEvent: Method in the main window. IOS developer: iOSDevTip

Case Column Analysis

Load an LGFirstView on the self. view of UIViewController.

The above LGFirstView has a UIButton. We call it buttonFirst.

Then, load a LGSecondView on the self. view, which is built on the LGFirstView.

There is also a UIButton on the LGSecondView. We call it buttonSecond.

Under normal circumstances:

When a user clicks LGSecondView (the clicked point is not on buttonSecond, but is it difficult to view it in buttonFirst), the event processing process is as follows:

1) Call the hitTest: withEvent: Method of the UIWindow. The hitTest: withEvent: method will call pointInside: withEvent: method. In this case, pointInside: withEvent: YES is returned, indicating that the touch event is on the UIWindow.

2) traverse the subview above the UIWindow, that is, self. view. Also, call the hitTest: withEvent: Method of self. view. hitTest: withEvent: method will call pointInside: withEvent: method. In this case, pointInside: withEvent: YES is returned, indicating that the touch event is on self. view.

3) traverse the sub-views on self. view, that is, LGFirstView and LGSecondView. (Note: The subview traversal sequence is from top to bottom, that is, traversing forward from the end of the subviews array ).

4) Call the hitTest: withEvent: Method of LGSecondView first. The hitTest: withEvent: method will call pointInside: withEvent: method. In this case, pointInside: withEvent: YES is returned, indicating that the touch event is on LGSecondView. (At this time, the LGFirstView will not be traversed, so the click event of buttonFirst will not be called as you wish)

5) before the end, go back to traverse all the child views on the LGSecondView. The result is that the hitTest: withEvent: Method of all the child views returns nil, because only secondButton is displayed on the LGSecondView, the click is not in secondButton.

6) The final hitTest: withEvent: method returns the current view itself (self), while LGSecondView has no event to handle. The whole process is over.

What if we want buttonFirst to respond to the click event? Method 1:

Add the following code to LGSecondView:

 

 

# Pragma mark-method 1-(id) hitTest :( CGPoint) point withEvent :( UIEvent *) event {UIView * hitView = [super hitTest: point withEvent: event]; if (hitView = self) {return nil;} else {return hitView ;}}

 

Let's analyze it again:

In this scenario, the user clicks LGSecondView (the clicked point is not in buttonSecond, but is it difficult to scatter in buttonFirst). The event processing process is as follows:

1) Call the hitTest: withEvent: Method of the UIWindow. The hitTest: withEvent: method will call pointInside: withEvent: method. In this case, pointInside: withEvent: YES is returned, indicating that the touch event is on the UIWindow.

2) traverse the subview above the UIWindow, that is, self. view. Also, call the hitTest: withEvent: Method of self. view. hitTest: withEvent: method will call pointInside: withEvent: method. In this case, pointInside: withEvent: YES is returned, indicating that the touch event is on self. view.

3) traverse the sub-views on self. view, that is, LGFirstView and LGSecondView. (Note: The subview traversal sequence is from top to bottom, that is, traversing forward from the end of the subviews array ).

4) Call the hitTest: withEvent: Method of LGSecondView first. The hitTest: withEvent: method will call pointInside: withEvent: method. In this case, pointInside: withEvent: YES is returned, indicating that the touch event is on LGSecondView.

5) but note that there is one here. However, UIView * hitView = [super hitTest: point withEvent: event]; that is, this code plays a role. If hitView is LGSecondView, click events are not processed. (This is different from userInteractionEnabled = NO. userInteractionEnabled = NO, And buttonSecond on LGSecondView does not respond to the click event .)

6) at this time, the hitTest: withEvent: Method of LGFirstView will be called, and the hitTest: withEvent: method will call pointInside: withEvent: method. In this case, pointInside: withEvent: YES is returned, indicating that the touch event is on LGFirstView.

7) traverse the sub-view above the LGFirstView, that is, buttonFirst. Call the hitTest: withEvent: Method of buttonFirst, And the hitTest: withEvent: method will call pointInside: withEvent: method. In this case, pointInside: withEvent: YES is returned, indicating that the touch event is on buttonFirst.

8) traverse all the sub-views on buttonFirst. The result is that the hitTest: withEvent: Method of all sub-views returns nil, indicating that the click is in buttonFirst, And the click method of the response is used.

Method 2

In LGSecondView. m

@ Interface LGSecondView ()

@ Property (nonatomic, strong) NSMutableArray * subControlsArray;

@ End

@ Implementation LGSecondView


-(Id) initWithFrame :( CGRect) frame
{
If (self = [super initWithFrame: frame]) {
Self. subControlsArray = [NSMutableArray array];
}
Return self;
}


# Pragma mark-method 2

-(Void) addSubview :( UIView *) view {
[Super addSubview: view];
If ([view isKindOfClass: [UIControl class]) {
[Self. subControlsArray addObject: view];
}
}

// Set self not response action and self subviews response action
-(BOOL) pointInside :( CGPoint) point withEvent :( UIEvent *) event;
{
BOOL toNext = YES;
For (UIView * view in _ subControlsArray ){
If (CGRectContainsPoint (view. frame, point )){
ToNext = NO;
Break;
}
}
Return! ToNext;
}

I will not go into details about the specific principles. You can also write down your ideas and send them to me.

There are still many ways to write down your ideas and send them to me. IOS developer: iOSDevTip

 

Related Article

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.