HitTest

이전 포스팅 Responder에 대해서 공부할 때, 잠깐 나왔던 개념이다.

 

정의는

Returns the farthest descendant of the receiver in the view hierarchy (including itself) that contains a specified point
지정된 점(point)을 포함하는 View 계층에서 리시버의 가장 먼 자손을 리턴한다.

라고 한다.

 

메소드이다.

 

point = 리시버의 bounds로 지점된 점

event = 메소드에 대한 호출을 보증하는 이벤트이다. 이벤트 처리코드 외부에서 이 메소드를 호출하는 경우에는 nil을 지정할 수 있다.

 

리턴 타입이 UIView?로 옵셔널이다.. nil이 반환될 수도 있다는 건데 -> 잠시 후에 알아보자

 

Discussion

이 메소드는 SubView의 point(inside:with:)를 호출하여 View 계층을 탐색하고, 어떤 하위 VIew가 터치 이벤트를 받아야 하는지 결정한다.

point 메소드의 파라미터는 hitTest와 같고, 반환타입만 다르다.

  • hitTest = 해당 point를 통해 리시버로부터 가장 먼 SubView를 반환
  • point = 해당 point가 리시버의 Bounds 내에 존재하는가?

point가 true를 반환하면, 하위 View 계층구조는 지정된 point를 포함하는 가장 앞에 있는 View를 찾을 때까지 재귀적으로 찾는다.

point가 false를 반환하면, View 계층 구조의 해당 분기가 무시된다.

(분기? -> hitTest는 Reverse DFS 방식으로 찾는다.)

ex) 

해당 View 계층일 때,

MainView -> View C -> View C.2 -> View C.1 -> View B ... 

순서로 찾게 된다.

 

왜? DFS면 DFS지 Reverse가 붙어?

-> iOS View 체계에서는 SubView가 SuperView보다 위(사용자에게 가까이)에 놓여진다.

-> 같은 SuperView를 가진 형제 View들의 경우에는 index가 늦은 View가 위에 놓여진다.

따라서, Reverse로 탐색할 때, hitTest가 성공한 최하단 SubView = 가장 위에 놓여진 View 가 된다.

 

 

hitTest 메소드의 동작 조건

  • hidden = false
  • alpha > 0.01
  • userInterationEnabled = true

리시버 Bounds 외부에 있는 point는 실제로 리시버 하위 View중 하나에 속하더라도, hit이 아니다.

-> Responder Chain에서의 GreenView와 같은 현상

 

hitTest 구현부

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    if (self.hidden || !self.userInteractionEnabled || self.alpha < 0.01 || ![self pointInside:point withEvent:event] || ![self _isAnimatedUserInteractionEnabled]) {
        return nil;
    } else {
        for (UIView *subview in [self.subviews reverseObjectEnumerator]) {
            UIView *hitView = [subview hitTest:[subview convertPoint:point fromView:self] withEvent:event];
            if (hitView) {
                return hitView;
            }
        }
        return self;
    }
}

조건문에 있듯이 hitTest의 동작 조건에 반하는 조건들이 if문에 걸려있다.

 

Why?

왜 hitTest를 알아야 하나?

Responder Chain 포스팅에서도 적었 듯

 

HitTest 테스트 포스팅

http://smnh.me/hit-testing-in-ios/

 

Hit-Testing in iOS

Hit-testing is the process of determining whether a point, such as touch-point, intersects a given graphical object, such as UIView, drawn on the screen. iOS uses hit-testing to determine which UIView is the frontmost view under the user’s finger that sh

smnh.me

 

 

 

 

 

'iOS' 카테고리의 다른 글

[iOS] View LifeCycle  (0) 2021.05.24
[iOS] UIWindowScene / UIWindow / UIView  (0) 2021.05.23
[iOS] Responder / Responder Chain  (0) 2021.05.21
[iOS] State Preserving/Restoring ViewControlle  (0) 2021.05.20
[iOS] App Life Cycle  (0) 2021.05.18

+ Recent posts