본문 바로가기
iOS/UIKit

[UIKit] UIResponder + Responder chain 흐름

by Kelly Chui 2025. 7. 21.

앱에서 터치 입력과 같은 유저 인터랙션을 처리하기 위해서 이 이벤트를 감지하고, 적절하게 처리할 방법을 찾는 것이 중요하다. UIKit에서는 이런 이벤트를 UIResponder 객체가 처리한다.

UIResponder와 UIEvent

개발자 문서에서 UIResponder는 '이벤트에 응답하고 처리하기 위한 추상 인터페이스'로 소개한다. 그렇다면 이벤트가 뭘까? UIKit에서 이벤트는 UIEvent 라는 클래스로 표현된다. 마찬가지로 개발자 문서에서 UIEvent는 '앱에서 단일 유저 인터랙션을 설명하기 위한 객체'로 소개된다.

가장 쉽게 볼 수 있는 리스폰더는 바로 UIView 객체이다. UIViewUIResponder를 서브클래싱 한 클래스이기 때문에, 자연스럽게 모든 UIView는 리스폰더가 된다. UIView 뿐만 아니라 UIViewControllerUIApplication 모두 UIResponder를 상속받는다.

UIKit 앱에서 터치 입력 이벤트는 UIEvent 객체로 포장되고, 이 객체를 UIResponder가 처리하는 것이다. 하지만 이벤트마다 어떻게 적절한 UIResponder 객체를 찾을 수 있을까?

Responder chain

리스폰더는 이벤트를 받고 처리하는 역할뿐만 아니라 다른 리스폰더에 이벤트를 전달해주는 역할도 한다. 앱에 이벤트가 발생했을때, 이를 처리할 리스폰더 객체에 전달하는 방법이 바로 Responder chain이다.

First responder

UIKit에서는 기본적으로 이벤트를 수신하면, 그 이벤트를 퍼스트 리스폰더(first responder)로 전달한다. 퍼스트 리스폰더는 현재 이벤트를 수신하기 가장 적절한 리스폰더가 선정된다. 예를 들면 텍스트 필드를 터치하면, 그 텍스트 필드가 퍼스트 리스폰더가 되어서 키보드를 화면에 띄우는 것을 생각하면 된다.

퍼스트 리스폰더를 정하는 기준은 정해져있다. 개발자 문서 아티클에선 다음과 같은 기준으로 퍼스트 리스폰더 선정 기준을 알려준다:

이벤트의 종류에 따라 퍼스트 리스폰더가 선정되는 기준이 다른 것을 알수 있다.

퍼스트 리스폰더 찾기

퍼스트 리스폰더가 되는 기준은 알았지만, 이제 그 퍼스트 리스폰더를 어떻게 찾는지도 알아보자. UIKit에서는 되게 직관적인 방법으로 터치 위치에 있는 뷰를 알아낸다. UIWindow 부터 시작해서 hitTest(\_:with:) 메소드를 재귀적으로 호출해서 가장 안쪽에 있는 UIView를 찾아내는 방식을 사용한다.

Event chain

하지만 퍼스트 리스폰더가 이벤트를 처리하지 못하는 경우를 생각해보자. 그러면 다음 리스폰더로 이벤트를 전달하게 된다. 이벤트를 처리하지 못하는 버튼을 생각해보자.

퍼스트 리스폰더는 버튼이 되겠지만, 이벤트를 처리하지 못했으므로 다음 리스폰더인 상위 뷰로 넘긴다, 만약 그 상위 뷰도 이벤트를 처리하지 못하면 이제 뷰 컨트롤러로... 이런식으로 타고 가면 최종적으로 UIApplication까지 올라가게 된다. 이렇게 이벤트가 리스폰더에서 리스폰더로 전달되는 과정이 Responder chain의 핵심이다. 만약 최종까지 올라갔는데 처리되지 못한다면, 그 이벤트는 그냥 아무 처리도 없이 사라지게 된다.

'iOS > UIKit' 카테고리의 다른 글

[UIKit] UIStackView 레이아웃  (0) 2025.07.17
[UIKit] UIView와 CALayer 사용하기  (0) 2025.07.17