cool hit counter iosHit-Test_Intefrankly


What is Hit-Test? To answer this first let's think about another question: when we click on the interface, how does iOS know which View we clicked on? This process is actually done by Hit-Test. With Hit-Test, the app can know which view is responding to events.

Here's a brief description of how hit-testing works

When you click on a view on the screen, the action is transmitted from the hardware layer to the operating system, and UIKit will package a UIEvent object, which will then be distributed to the currently active App. After informing the currently active App of the event, the UIApplication instance will fetch the latest event from the event queue and distribute it to the object that can handle the event. After UIApplication gets the Event, Application is stuck on what event to pass to that View to respond to the event, and it's up to HitTest to decide.

In iOS, the role of Hit-Test is to find out what is the View below this touch point. HitTest will detect whether this clicked point occurs on this View, and if so, it will go through the subviews of this View until it finds the smallest view that can handle the event, and if the whole circle does not find a view that can handle it, it returns itself Then start looking again from the sub View. But the question arises in what order does hit-testing find the SubView. In other words, you start with the top-level SubView.

as shown below


The user clicks on View D and the hit-test view flows as follows:

  1. A is the root view of the UIWindow and, therefore, the UIWindow object will first hit-test A.
  2. apparently the user clicked within the scope of A, so pointInside:withEvent: returned YES, at which point it continues to check the subviews of A.
  3. B view branch of pointInside:withEvent: returns NO and the corresponding hitTest:withEvent: returns nil.
  4. the range of the click is within C, i.e. C's pointInside:withEvent: returns YES; at this point there are two branches, D and E: the range of the click is then within D view, so D view's pointInside:withEvent: returns YES and the corresponding hitTest:withEvent: returns DView.

Code Validation Create a new BaseView base class

#import "BaseView.h"

@implementation BaseView

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
     // 1. Determine if the current control can receive events
    if (self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <= 0.01) {return nil;}
     // 2.  Determine if the point is in the current control or not
    if ([self pointInside:point withEvent:event] == NO) {return nil;}

     // 3. Iterate over your own child controls from back to front
    NSInteger subViewCoutn = self.subviews.count;

    for (NSInteger i = subViewCoutn - 1; i >= 0; i--) {
         // Fetch the subView
        UIView *childView = self.subviews[i];
         // Convert the coordinate system on the current control to the coordinate system on the child control
        CGPoint childP = [self convertPoint:point toView:childView];
         // Find the most suitable view
        UIView *fitView = [childView hitTest:childP withEvent:event];
        if (fitView) {
            return fitView;
    NSLog(@" Clicked.:%@",NSStringFromClass([self class]));

     // The loop ends, indicating that there is no more suitable view than itself
    return self;

A, B, C, D, E View inherits BaseView

When we click on DView the console prints

2018-09-01 08:57:56.516949+0800 HitTest[856:19095898]  Clicked.:DView

Hit-Test in action

Simulator Screen Shot - iPhone X - 2018-09-01 at 08.59.54_gaitubao_com_217x470.png

As shown above, the B view adds a Button, at this time click the button beyond the scope of the B view, the button click event is not working, at this time the console will print.

2018-09-01 08:57:56.516949+0800 HitTest[856:19095898]  Clicked.:AView

If the user clicks on a button that is outside the scope of the BView, the Hit-Test is also useful, and we modify the code of the BView

The B View code is as follows

#import "BView.h"

@interface BView()

@property (strong, nonatomic) UIButton *btn;


@implementation BView

- (instancetype)initWithCoder:(NSCoder *)aDecoder
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self setButton];
    return self;

- (void)setButton
    self.btn = [UIButton buttonWithType:UIButtonTypeCustom];
    self.btn.frame = CGRectMake(100, -20, 150, 40);
    self.btn.backgroundColor = [UIColor blueColor];
    [self.btn setTitle:@" I am aButton" forState:UIControlStateNormal];
    [self.btn addTarget:self action:@selector(btnAction:) forControlEvents:UIControlEventTouchUpInside];
    [self addSubview:self.btn];

- (void)btnAction:(UIButton *)sender
    NSLog(@" Clicked the button");

// Addressing invalid out-of-area clicks
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    if (self.isHidden == NO) {
        //  Convert coordinates
        CGPoint newPoint = [self convertPoint:point toView:self.btn];
        //  Determine if the clicked point is within the button area
        if ( [self.btn pointInside:newPoint withEvent:event]) {
            // Back button
            return self.btn;
            return [super hitTest:point withEvent:event];
    else {
        return [super hitTest:point withEvent:event];

Clicking on a button outside of the BView range will also output: button clicked. OK the problem is solved and Hit-Test is pretty much understood. Start your show!!!


1、White Blognbsplinux Directory structure
2、Spring internship facetoface experience sharing have gotten Tencent spring recruitment Offer
3、7 days online 150 million in funding completed can Bullet SMS really disrupt WeChat
4、Resolving Hadoop startup errors
5、Amazon Cloud Services AWS The ECommerce Giants Biggest Business of the Future

    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送