---
# System prepended metadata

title: Responder Chain

---

## 👨‍🔬 실험 1

```swift
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
    if !isUserInteractionEnabled || isHidden || alpha <= 0.01 {
        return nil
 
    }
 
    if self.point(inside: point, with: event) {
        for subview in subviews.reversed() {
            let convertedPoint = subview.convert(point, from: self)
            if let hitTestView = subview.hitTest(convertedPoint, with: event) {
                return hitTestView
            }
        }
        return self
    }
    return nil
}
```
- 우리가 orangeView 위의 한 지점을 터치했을 때, UIKit 은 어떤 뷰의 hitTest 를 가장 먼저 호출할까요?
- hitTest 가 호출 되었을 때, 코드의 내부 흐름이 어떠할지 떠올려봅시다.
- hitTest를 override하기 위해 각 View를 CustomView 타입으로 지정합니다.
    - hitTest를 override 하고, 위의 코드로 대체해봅시다.
    - 터치한 위치의 가장 상위 뷰를 콘솔창에 print 할 수 있도록, hitTest를 코드 내부를 수정해봅시다.
    ```swift
    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        if !isUserInteractionEnabled || isHidden || alpha <= 0.01 {
            return nil
        }
        
        if self.point(inside: point, with: event) {
            for subview in subviews.reversed() {
                let convertedPoint = subview.convert(point, from: self)
                if let hitTestView = subview.hitTest(convertedPoint, with: event) {
                    print("background : \(String(describing: hitTestView.backgroundColor?.accessibilityName))")
                    return hitTestView
                }
            }
            if !subviews.isEmpty {
                print("background2 : \(String(describing: self.backgroundColor?.accessibilityName))")
            }
            return self
        }
        return nil
    }
    ```
    - 다음 위치를 터치하며, 그 결과가 나온 과정을 추론해봅시다.
        - orangeView 위를 터치
            오렌지를 출력합니다.
        - greenView 위를 터치
            그린을 출력합니다.
        - purpleView 위를 터치 (주목!)
            - 겹쳐 있는 부분을 터치한 경우
                출력이 됩니다
            - 겹쳐있지 않은 부분을 터치한 경우
                출력되지 않습니다.
                - 왜 그러한 결과가 일어났을까요?
                 `hitTest(_:with:)` 메서드는 특정 좌표가 뷰의 영역에 속하는지를 검사(ex. `point(inside:with:)`이용)하고, 해당 뷰를 반환합니다. 이 때, `hitTest(_:with:)` 메서드는 뷰 계층 구조의 최상위 뷰부터 시작하여 하위 뷰들을 검사합니다. 따라서 버튼이 뷰의 경계를 벗어난 위치를 클릭했을 때, 해당 위치에 대한 터치 이벤트를 처리할 뷰를 찾는데 실패하게 됩니다.
        - blueView 위를 터치
- BlueView에는 UIButton을 올린 후, 반쯤 걸치도록 구성합니다.
    - 이때 BlueView와 겹치지 않은 Button의 영역을 터치했을 때 어떤 일이 일어날까요?
        - 터치가 되지 않습니다.
        - 왜 그러한 결과가 일어났을까요?
        - 위와 동일한 이유

### 메서드
[**point(inside:with:)**](https://developer.apple.com/documentation/uikit/uiview/1622533-point)
수신자에 지정된 지점이 포함되어 있는지 여부를 나타내는 bool 값을 반환

return value: 포인트가 수신자의 bound 안에 있으면 true, 아니면 false