앱은 responder object를 통해 event를 받고 핸들링합니다. 여기서 responder object는 UIResponder의 인스턴스를 말하는데, UIView, UIViewController, UIApplication의 subsclass들이 일반적으로 responder object가 됩니다.
Responder object는 raw event data를 받고 처리하거나 다른 responder object에게 전달(forwarding) 해야 합니다. app이 event를 받으면 UIKit이 자동으로 적절한 responder object(first respnder)에게 전달합니다.
iOS → App(UIApplication) → (First) Responder object
처리되지 않은 이벤트는 유효한 responder chain 내에서 responder에서 responder로 전달됩니다.
which is the dynamic configuration of your app’s responder objects.
Figure 1 Responder chains in an app
다이어그램은 responder chain에 따라 하나의 responder에서 다른 responder로 어떻게 이벤트가 이동하는지를 나타냅니다.
UIKit는 이벤트 타입에 따라 first responder object를 지정합니다.
accelerometers, gyroscopes, magnetometer와 관련된 motion event들은 responder chain를 따르지 않습니다. 대신 Core Motion이 이벤트를 지정된 object에게 directly 전달합니다.
accelerometers : shake
gyroscopes : 회전
magnetometer : ?
Controls은 관련된 target object와 action message를 사용해서 직접적으로 커뮤니케이션 합니다. (target- action)
user가 control을 사용해서 상호작용하면 control은 action message를 target object에 보냅니다.
action message는 event가 아니지만, responder chain을 이용합니다.
target object가 nil
이면, UIKit는 action method를 구현한 객체부터 responder chain으로 target을 탐색(traverse)합니다.
UIControl은 action message를 전달할 target을 찾기 위해 responder chain을 이용하기도 한다.
예를 들면, UIKit editing menu가 cut, copy, paste 와 같은 동작을 구현할 responder object를 찾기 위해 responder chain이 일어납니다.
Gesture recognizer가 view보다 먼저 touch and press 이벤트를 받습니다. 뷰의 gesture recognizer가 이벤트를 인식하는데 실패하면 UIKit가 이벤트를 뷰에게 보냅니다.
view가 이벤트를 처리하지 못하면, UIKit는 responder chain에 따라 전달합니다.
UIKit은 view를 기반으로 한 hit-testing으로 touch event가 발생한 뷰를 결정합니다. 특히 view 계층 구조 내 view 객체의 가장자리를 비교해서 결정합니다. hitTest(_:with:)
메소드는 뷰의 hierarchy를 돌면서 가장 깊은 subview를 찾고, 그 객체가 touch event를 받을 first responder가 됩니다.
view를 기반으로 한 hit-testing으로 touch event를 처리할 뷰를 결정한다.
hit-testing은 UIView 안에 정의된hitTest(_:with:)
를 통해 이루어진다.
touch가 발생하면, UIKit은 UITouch object를 생성하고, 뷰와 연결시킵니다. touch 위치 또는 다른 parameters 변화에 따라 UIKit는 동일한 UITouch object를 새로운 정보와 함께 업데이트합니다. 하지만 touch 객체의 view property는 변하지 않습니다. touch가 끝나면 UIKit이 UITouch object를 release 합니다.
touch event가 발생하면 UIKit가 UITouch 객체를 생성해서 (hit-testing을 통해 찾은) view와 연결한다.
touch 객체의 view property에 assign. touch 위치가 변하더라도, view 속성 값은 변하지 않는다.
touch가 끝나면(touchesEnded()
가 호출되면) UIKit가 touch object를 release(메모리에서 해제) 한다.
// UIResponder
func touchesBegan()
func touchesMoved()
func touchesEnded()
func touchesCancelled() // 전화, 문자 등으로 터치 이벤트가 interrupte 된 경우
responder object의 next
property를 오버라이딩해서 responder chain을 변경할 수 있습니다.
이미 많은 UIKit class들이 next property를 오버라이딩해서 특정 객체를 리턴하고 있습니다. 가령:
@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 }
// ...
}