IOS hit-test App

Source: Internet
Author: User

I recently looked at Apple's official document "event handling guide for IOS", hit-test view in the incident response chain, and a little more understanding, the official document of the individual feel is very simple to this piece, many things are donuts, the knowledge of Hit-test view is used everywhere in the project, but I can not perceive it, and then I will tell you about the three applications that can solve the pain point in the hit-test View project.

What do you mean hit-test view? The document says: Thelowest view in the view hierarchy this contains the touch point becomes the hit-test view, which I understand is: When you click on the screen A view, which is transmitted from the hardware layer to the operating system and then encapsulated as an event from the bottom to the top of the view hierarchy, has been found to contain this point of click and the highest level (the document is said to be the lowest, I understand that the view, which is logically closest to the finger, responds to the event, which is hit-test view.

The document says that deciding who Hit-test view is by constantly recursively calling the view in the -(UIView *) Hittest:withevent: method and -(BOOL) Pointinside: Withevent: method to achieve, this paragraph in the paragraph is too good to understand, so I modeled in the official document this picture made a demo----GitHub address


Apple doucument pic

The view method in the overloaded graph adds the corresponding log for easy observation:

In every view. M overide those methods-(UIView *) HitTest: (Cgpoint) point withevent: (Uievent *) Event {NSLog (@ "Enter A_view---hitTest withevent---");UIView * view = [Super Hittest:point Withevent:event];NSLog (@ "Leave A_view---hitTest withevent---hittestview:%@", View);return view;} - (BOOL) Pointinside: (Cgpoint) Point withevent: (NullableUievent *) Event {NSLog (@ "A_view---pointinside withevent---");BOOL isinside = [Super Pointinside:point Withevent:event];NSLog (@ "A_view---pointinside withevent---isinside:%d", isinside);return isinside;} -(void) Touchesbegan: (nsset *) touches withEvent: (uievent *) event{nslog (@ "A_ Touchesbegan ");} -(void) touchesmoved: (nsset< uitouch *> *) touches withevent: (Nullable UIEvent *) event {nslog (@ "a_touchesmoved");} -(void) touchesended: (nsset< uitouch *> *) touches withevent: (Nullable UIEvent *) event {nslog (@ "a_touchesended");      

Click View_d in the picture to see what happens.


View_d Log

One is to find Touchesbegan, touchesmoved, touchesended These methods occur after finding hit-test view , Because the touch event is for a certain view that can respond to an event, such as your finger scrollview the range, as long as you do not let go and continue to slide, ScrollView will still respond to the sliding events continue to scroll, and the second is to find hit-test view Chain of events conducted two times, and two times the call stack is different, I am a bit confused, why need two times, look up a lot of data also do not know why, found that the real machine and simulator and different system version there will be some difference between (this is true machine iOS9), you can download my demo for testing and research.

Replace the search logic with the following code:

- (UIView *) HitTest: (Cgpoint) point withevent: (Uievent *) Event {if (!Self. isuserinteractionenabled | |Self. Ishidden | |Self. Alpha <=0.01) {return nil;} if ([self pointinside:point Withevent:event]) { for (uiview *subview in [self.subviews Reverseobjectenumerator]) { cgpoint convertedpoint = [Subview convertpoint:point fromview: self]; uiview *hittestview = [Subview hittest:convertedpoint withevent:event]; if (hittestview) {return Hittestview;}} return self;} return nil;}        

If there are two sub-view locations in a view that overlap, according to the visually in the View Programming Guide for iOS document , the content of a subview obscures all or part of The content of its parent view. If the subview is totally opaque and then the area occupied by the Subview completely obscures the corresponding area of the Parent. If the subview is partially transparent, the content from the the the the the the the the and the the the other is blended together prior to being displayed on th E screen. Each Superview stores it subviews in a ordered array and the order in this array also affects the visibility of each sub View. If the sibling subviews overlap, the one that is added last (or is moved to the end of the Subview array) app Ears on top of the other. The top (logic closest to the finger) view is the last element of the view Subviews array, and the logic of Hit-test view is still valid as long as the search is being traversed from the first element of the array.

When the hit-test view is found, it has the highest priority to respond to the event that is passed up, such as the superview that it cannot respond to, and so on, which is passed to uiapplication without a responder. This event will be discarded by the system.

Hit-test View Application Example: 1, expand the response of the UIButton hot zone

I believe everyone has encountered a small map button click Hot Zone too small problem, before I was using UIButton setimage method to set up the picture resolution, but the coordinates on the pit, to calculate the number of not say, write code is also difficult to see not easy to maintain, if we use Hit-test View knowledge you can easily solve this problem.

Overloaded UIButton -(BOOL) Pointinside:withevent: method that allows point to return yes even if it falls on the perimeter of the button's frame.

In custom button. mOveride This method-(BOOL) Pointinside: (Cgpoint) Point withevent: (NullableUievent *) Event {ReturnCgrectcontainspoint (Hittestingbounds (Self. Bounds,Self. Minimumhittestwidth,Self. minimumhittestheight), point);}CGRect Hittestingbounds (CGRect Bounds,CGFloat Minimumhittestwidth,CGFloat minimumhittestheight) {CGRect hittestingbounds = bounds;if (Minimumhittestwidth > Bounds. Size. width) {hittestingbounds. Size. width = minimumhittestwidth; Hittestingbounds.origin.x-= (hittestingbounds .size.width-bounds.size< Span class= "hljs-variable" >.width)/2;} if (Minimumhittestheight > Bounds.size.height) {hittestingbounds.size.height = Minimumhittestheight; Hittestingbounds.origin.y-= (HitTestingBounds.size.height-bounds.size.height)/2;} return hittestingbounds;}          
2. Child view exceeds bounds response event of Parent view

A project often encounters a button that is outside the scope of the parent view but still needs to be clickable, such as a custom tabbar large button in the middle, such as a free fish app, and a response when clicking on an area beyond the Tabbar bounds, which overloads the parent view's -(UIView * Hittest:withevent: method, remove the click must be in the parent view of the judgment, and then the child view can become hit-test view in response to the event.


Xiansyu
- (UIView *) HitTest: (Cgpoint) point withevent: (Uievent *) Event {if (!Self. isuserinteractionenabled | |Self. Ishidden | |Self. Alpha <=0.01) {ReturnNil }/** * This commented out method is used to determine whether the click is within the parent view bounds, * if not in the parent view, will not go to its child view to look for Hittestview,return return *///if ([self pointinside:point withevent:event]) {for (UIView *subview in [self. Subviews Reverse Objectenumerator]) { Cgpoint convertedpoint = [Subview convertpoint:point fromview: Self]; UIView *hittestview = [Subview hittest:convertedpoint withevent:event]; if (hittestview) { return hittestview;}} return self ;  } return nil;}               
3. ScrollView Page Swipe

This is the App cover preview feature of App Store app


ScrollView page

The interaction is often seen in many posters, cover display of the app, the way to achieve this interaction has a lot, but choose to use ScrollView to cross-slide to do is the simplest, let Scrollview.pageenabel = YES, there is the feeling of page flipping, But so the actual sliding area of the Scoreview is only a single photo so wide, what if you want the distance left by the side (the Blue box part) to respond to the sliding event? This time again can use the knowledge of Hit-test view, in the ScrollView's parent view of the blue part of the event is passed to ScrollView can be, the specific look at the following code:

//in scrollView.superView .m- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {    UIView *hitTestView = [super hitTest:point withEvent:event]; if (hitTestView) { hitTestView = self.scrollView; } return hitTestView;}
Summarize

The event response chain is a very important concept in the UI layer, and it is necessary to have an in-depth understanding of how to make great interactions and animations. I am only listing some of the problems I have encountered in the development, if there are other applications to the incident response chain I hope you and I will share the discussion.



Original link: http://www.jianshu.com/p/d8512dff2b3e

IOS hit-test App

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.