A view of iOS-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event method is executed, depending on whether the click point is within the scope of its parent view

First, we look at the execution logic of the hittest method by looking at the call stack

As shown in the above two figures, the calling logic of hittest is like this, starting from the window, calling hittest, in this method again

To call the hittest method of all subviews, point inside will be called in the hittest method,

Judge whether the click point is within its own range, if it is within its own range, call the hittest method of the child control

In other words, whether a view calls the hittest method depends on whether the click point is within the scope of its parent view

 

Principle: See if the touch point is on yourself, and finally traverse the child controls from back to front. When traversing the child controls, repeat the previous two steps again, and then convert the coordinate points on the parent control to the coordinate system of the child control. Click and execute the hitTest method again to traverse.

The principle pseudo code is as follows


- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    //系统默认会忽略isUserInteractionEnabled设置为NO、隐藏、或者alpha小于等于0.01的视图
    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;
}

 

Code verification

As shown in the figure, click the blank space

As shown in the figure, click on the empty table, the hittest of view a is executed, but view b is not executed, and the parent view of view a is

vc view, the parent view of b view is a, because the click point is within the range of vc view (a’s parent view), so the hittest method of a view is executed,

But the click point is not within the scope of view a (the parent view of b), so the hitest method of view b is not executed 

In addition, we also found that we can’t actively call the hittest method, we can only rewrite it, and the returned view of the active call is empty.

This method can only be overridden and cannot be called

But point inside can be actively called

Guess you like

Origin blog.csdn.net/LIUXIAOXIAOBO/article/details/113067527