iOSのビュー-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)eventメソッドは、クリックポイントがその親ビューのスコープ内にあるかどうかに応じて実行されます

まず、コールスタックを見て、ヒットテストメソッドの実行ロジックを確認します。

上の2つの図に示されているように、hittestの呼び出しロジックは次のようになり、ウィンドウから開始して、このメソッドで再びhittestを呼び出します。

すべてのサブビューのhittestメソッドを呼び出すために、内部のポイントがhittestメソッドで呼び出されます。

クリックポイントが独自の範囲内にあるかどうかを判断し、独自の範囲内にある場合は、子コントロールのヒットテストメソッドを呼び出します

つまり、ビューがhittestメソッドを呼び出すかどうかは、クリックポイントがその親ビューのスコープ内にあるかどうかによって異なります。

 

原則:タッチポイントが自分自身にあるかどうかを確認し、最後に子コントロールを後ろから前にトラバースします。子コントロールをトラバースするときは、前の2つの手順をもう一度繰り返してから、親コントロールの座標点をの座標系に変換します。子コントロール。クリックしてもう一度hitTestメソッドを実行し、トラバースします。

主要な擬似コードは次のとおりです


- (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;
}

 

コード検証

図のように、空白部分をクリックします

図に示すように、空のテーブルをクリックすると、ビューaのヒットテストが実行されますが、ビューbは実行されず、ビューaの親ビューは実行されます。

vcビュー、bビューの親ビューはaです。これは、クリックポイントがvcビュー(aの親ビュー)の範囲内にあるため、ビューの最もヒットしたメソッドが実行されるためです。

ただし、クリックポイントはビューa(bの親ビュー)の範囲内にないため、ビューbの最もヒットしたメソッドは実行されません。 

さらに、hittestメソッドをアクティブに呼び出すことはできず、書き換えることしかできず、アクティブな呼び出しの返されたビューはすべて空であることがわかりました。

このメソッドはオーバーライドのみが可能で、呼び出すことはできません

しかし、内部のポイントは積極的に呼び出すことができます

おすすめ

転載: blog.csdn.net/LIUXIAOXIAOBO/article/details/113067527