Responder Object and UIResponder Class

Martin·2023년 2월 18일

TIL 아카이브

목록 보기
9/11

Responder

이벤트를 핸들링하고 이벤트에 반응할 수 있는 객체

  • 모든 Responder 객체는 UIResponder에서 상속된 클래스들의 인스턴스 (UIApplication, UIViewController, UIView, UIWindow 객체 등) 많은 주요 객체들이 Responder
  • UIKit은 이벤트 핸들링을 위해 Responder 객체들에게 보냄
  • 이벤트 종류 : 터치, 모션, 원격 조종, press 등등
  • 특정 이벤트를 핸들링하기 위해서는 responder가 해당 이벤트에 대응되는 메서드들을 오버라이드하여 구현 해야 함
    예시 : 터치 이벤트 핸들링
    responder가 touchesBegan(:with:), touchesMoved(:with:), touchesEnded(:with:), touchesCancelled(:with:) 메서드를 구현해야 함, responder는 터치의 변화를 트래킹하고 앱의 인터페이스를 적절히 업데이트하기 위해서 UIKit에서 제공하는 이벤트 정보를 이용
  • Responder들은 UIEvent 객체를 처리할 수도 있고, input view를 통해 커스텀 input을 받아들일 수도 있음
    시스템 키보드가 이 input view에 대한 가장 명료한 예시, 사용자가 화면의 UITextField 또는 UITextView 객체를 탭하면, 해당 뷰는 first responder가 되고, input view를 디스플레이입니다.
  • UIKit에 정의되어 있는 UIResponder 클래스
@available(iOS 2.0, *)
open class UIResponder : NSObject, UIResponderStandardEditActions {

    open var next: UIResponder? { get }
    
    open var canBecomeFirstResponder: Bool { get } // default is NO
    open func becomeFirstResponder() -> Bool

    open var canResignFirstResponder: Bool { get } // default is YES
    open func resignFirstResponder() -> Bool

    open var isFirstResponder: Bool { get }
    // ...
}

The Responder Chain

Responder 객체들이 이벤트나 액션 메시지를 핸들링할 책임을 앱의 다른 객체들에게 전송할 수 있도록 함

  • 특정 정해진 responder가 이벤트를 핸들링하지 않을 경우, 해당 reponder는 그 이벤트를 reponder chain의 다음 객체에게로 포워딩
  • 메시지는 처리될 때까지 계속 chain의 상위 객체들로 이동
  • 마지막까지 처리되지 않을 경우, 앱이 해당 메시지를 버림

The path of an event

  • UIKit은 일정한 규칙을 사용하여 responder chain을 동적으로 관리하는데, 이 규칙에 의해 어떤 객체가 다음 순서로 이벤트를 받을지가 결정
    예를 들어, 뷰는 뷰의 슈퍼뷰에게로 이벤트를 포워딩하고, 뷰 계층의 루트 뷰는 루트 뷰의 뷰 컨트롤러에게로 이벤트를 포워딩
이벤트가 responder chain을 따라 한 responder에서 다음 responder로 이동하는 내용 예시

  • Text field가 이벤트를 핸들링하지 않으면, UIKit은 text field의 부모인 UIView 객체에게로 이벤트를 보내고, 이어서 윈도우의 루트 뷰에게로 보냅니다.
  • 루트 뷰에서, Responder chain은 이벤트를 윈도우로 보내기 전에 방향을 바꾸어 루트 뷰를 소유하고 있는 뷰 컨트롤러에게로 보냅니다.
  • 만약 윈도우가 이벤트를 처리하지 못하면, UIKit은 이벤트를 UIApplication 객체에게로 보냅니다. 그리고 app delegate가 UIResponder의 인스턴스이고 responder chain의 일부가 아니라면 이벤트를 app delegate에게로 보냅니다.

The First Responder

앱에서 많은 종류의 이벤트들을 처음으로 받는 responder 객체, 대체로 앱이 이벤트를 핸들링하기 가장 적합하다고 간주하는 responder 객체

  • 이벤트를 받기 위해서는, responder는 자신이 first responder가 될 수 있음을 나타내야 함
  • first responder가 될 수 있게 하려면, UIResponder의 서브클래스에서 canBecomeFirstResponder 프로퍼티를 오버라이드하여 true를 리턴하도록 만들어야함
  • 이벤트 메시지들을 받는 것 이외에, responder는 target이 특정되지 않은 액션 메시지들을 받을 수도 있습니다. (액션 메시지들은 버튼이나 사용자가 조절 가능한 control들 등 컨트롤들로부터 보내집니다.)

Determining an Event’s First Responder

UIKit은 받은 이벤트의 종류에 따라서 특정 객체를 해당 이벤트의 first responder로 지정

Event typeFirst responder
Touch events터치가 일어난 뷰
Press events포커스를 가진 뷰
Shake-motion eventsUIKit이 지정한 객체 또는 직접 지정
Remote-control eventsUIKit이 지정한 객체 또는 직접 지정
Editing menu messagesUIKit이 지정한 객체 또는 직접 지정
  • 컨트롤은 연관된 타겟 객체와 직접 액션 메시지를 이용해 소통
  • 액션 메시지는 이벤트는 아니지만 responder chain을 이용
  • 컨트롤의 타겟 객체가 nil일 경우, UIKit은 first responder에서 시작하여 적절한 액션 메시지를 구현한 객체를 만날 때까지 responder chain을 따라 이동
profile
제로부터 시작하는 이세계 Swift

0개의 댓글