[기초부터 iOS] 앱이 이벤트를 처리하는 방법 - Responder Chain

Wody·2023년 3월 26일
0

기초부터 iOS

목록 보기
1/1
post-thumbnail

Responder Chain

Responder Chain은 앱이 Responder 객체를 통해 이벤트를 수신하고 처리하는 과정을 의미합니다.

Responder 객체...? 그래서 Responder 객체가 뭔데??

Responder 객체는 말 그대로 UIResponder class를 의미합니다.
UIResponder 클래스는 이벤트에 응답하고 처리하기 위한 추상적인 인터페이스 라고 공식문서에서 소개하고 있는데,
간단하게 이야기하면 UIKit을 사용하는 앱의 이벤트를 처리하기 위한 클래스이며 UIView, UIViewController 도 UIResponder 객체임을 알 수 있습니다.

// Apple 공식문서의 Declaration 참조
@MainActor class UIView : UIResponder
@MainActor class UIViewController: UIResponsder

아하! Responder 객체는 이벤트에 응답하고 이벤트를 처리하기 위한 클래스였구나!
그럼 어떻게 이벤트가 발생했는지 알고, 어떤 객체가 이벤트를 처리해야 하는지 알 수 있을까?

앱에 이벤트가 발생하면 UIKit이 이벤트를 첫 번째 Responder에게 전달하는데, 만약 첫 번째 Responder가 이벤트를 처리하지 못한다면 다음 Responder에게 이벤트를 전달합니다.

음... 만약 A View가 이벤트를 처리하지 못하면 A View의 Super View에게 이벤트를 전달하고...
만약 super 뷰도 이벤트를 처리하지 못하면 view hierarchy(계층구조)를 따라 이벤트를 전달하다가...
이벤트를 수신할 View가 없다면 ViewController에게! 그리고 최종적으로 UIWindow와 UIApplication까지 도달하는구나!

이렇게 앱에 발생한 이벤트를 처리하는 객체가 UIResponder 타입이고,
UIResponder가 이벤트를 처리하기 위해 이벤트를 받고 다른 Responder에게 전달하거나 처리하는 과정을 Responder Chain이라 말하는 것입니다.

이벤트의 종류

앞서 이야기했던, 앱에서 발생한 이벤트를 처리하기 위한 UIKit의 시스템 Responder Chain 알아보았습니다.
그럼 근본적으로 앱에 발생 할 수 있는 이벤트는 무엇이 있을까요? 공식문서에 따르면 다음과 같이 있습니다.

  • Touch events : 화면에 손가락 터치가 발생했을 때, 탭 / 드래그 / 스와이프 / 핀치 등으로 다양하게 상호작용에 따라 터치 이벤트 발생
  • Press events : 하드웨어 장치의 물리 버튼을 눌렀다 때거나 길게 누르는 이벤트
  • Shake-motion events : 디바이스를 흔들거나 움직였을 때 발생하는 이벤트, 특별하게 모션 이벤트는 responder 체인이 아닌 Core Motion Framework에 의해 처리된다.
  • Remote-control events : 외부 악세서리(블루투스 장비, 에어팟 등)를 통해 앱을 제어할 때 발생하는 이벤트
  • Editing menu messages : 텍스트를 선택하거나 길게 누를 때 편집 메뉴가 뜨는 이벤트, 복사 / 붙어넣기 / 모두 선택 ... 등 이벤트

Touch event의 First responder 찾기

이벤트가 발생하면 UIKit이 이벤트를 첫 번째 Responder에게 전달한다고 했는데, 첫 번째 Responder는 어떻게 결정되는 걸까요?

UIKit은 뷰 기반의 hitTest() 메서드를 통해 터치 이벤트가 발생하는 위치를 결정합니다.
hitTest는 터치 이벤트가 발생한 곳을 기준으로 뷰의 계층 구조를 비교하는데,
만약 터치 위치가 뷰의 bounds를 벗어났다면 위치를 벗어난 뷰와 모든 하위 뷰를 무시합니다. (포인트가 뷰 계층 구조 밖에 있을 경우 nil을 반환하기 때문)
반대로 터치 이벤트가 발생한 곳을 기준으로 hitTest 메서드는 뷰 계층 구조에서 가장 끝에 있는 뷰 객체를 반환하게 되는데 이는 뷰 계층 구조에서 스크린에 가장 맞닿아 있는 뷰를 의미합니다.
(뷰 계층 구조상 가장 끝, 혹은 가장 먼 후손이라 표현하기도 하지만 스크린을 바라보는 기준 맨 첫 번째 뷰를 의미합니다)

Responder Chain 이 이뤄지는 방법

지금까지 앱에 이벤트가 발생하면 어떻게 이벤트를 수신(hitTest)하고 처리(events)하는지 알아보았습니다.
마지막으로 이 글의 핵심인 Responder chain이 어떻게 이뤄지는지 알아보겠습니다.

responder가 이벤트를 적절히 처리하지 못할 경우 next 속성에 의해 다음 responder chain에게 이벤트가 전달되는데요.
만약 이 속성을 overriding 한다면 다음 responder는 개발자가 직접 설정한 객체가 응답하게 됩니다.

0개의 댓글