티스토리 뷰

iOS

iOS ) UIResponder

Zedd0202 2018. 5. 26. 23:59
반응형

안녕하세요 :) Zedd입니다.

오늘은 UIResponder를 공부해보려고 해요.



UIResponder



리스폰더 객체(Responder objects), 즉 UIResponder의 인스턴스는 UIKit 앱 이벤트 처리 백본(backbone)을 구성합니다.

많은 핵심 객체는 UIApplication객체, UIViewController객체 및 모든 UIView객체(UIWindow포함)을 포함하여 리스폰더입니다. 

(UIApplication객체, UIViewController객체, UIView객체가 모두 리스폰더라는 소리 ㅇㅇ)

이벤트가 발생하면, UIKit은 이를 처리할 수 있도록 앱의 리스폰더 객체에 전달합니다. 

즉, UIApplication객체, UIViewController객체, UIView객체가 이 이벤트를 다룰 수 있다는 거겠죠?


터치이벤트, 모션이벤트, 원격제어 이벤트 및 press이벤트를 비롯한 여러 종류의 이벤트가 있습니다. 특정 타입의 이벤트를 처리하려면, 리스폰더가 해당 메소드를 override해야합니다 (To handle a specific type of event, a responder must override the corresponding methods)


예를들어 터치 이벤트를 처리하기 위해 리스폰더는 touchesBegan(_:with:)touchesMoved(_:with:)touchesEnded(_:with:), 그리고 touchesCancelled(_:with:) 를 구현합니다. 터치이벤트의 경우, 리스폰더는 UIKit에서 제공한 이벤트 정보를 사용하여 해당 터치의 변경사항을 추적하고, 앱의 인터페이스를 적절하게 업데이트해야합니다.


이벤트처리 이외에도 UIKit 리스폰더는 처리되지 않은 이벤트를 앱의 다른 부분으로 전달하는 작업을 관리합니다. 

주어진 리스폰더가 이벤트를 처리하지않으면, 리스폰더 체인의 다음 이벤트로 해당 이벤트를 전달합니다. UIKit은 미리 정의된 규칙을 사용하여 리스폰더 체인을 동적으로 관리하여 어떤 객체가 이벤트를 수신한 다음에 어떤 객체를 선택할지 결정합니다. 예를들어 View는 이벤트를 상위 View로 전달하고, 계층의 루트 View는 이벤트를 해당 ViewController로 전달합니다. 


리스폰더는 UIEvent객체를 처리하지만, input View를 통해 사용자 정의 input을 허용 할 수 있습니다. 시스템의 키보드는 input View의 가장 분명한 예입니다. 사용자가 UITextField및 UITextView객체를 화면 상에서 tap하면 View가 첫번쨰 리스폰더가 되어 시스템 키보드 input View가 표시됩니다. 마찬가지로, 시스템 정의 input View를  만ㄷ르어 다른 리스폰더가 활성ㄷ화 될 떄 표시할 수 있습니다. 사용자 지정 input View를 리스폰더와 연결하려면, 해당 View를 리스폰더의 inputView프로퍼티에 할당합니다.



혹시 리스폰더 체인이라고 들어보셨나요?

(위에서 언급했지만..)


"리스폰더"라는게 이벤트를 처리할 수 있는? 앱의 이벤트 처리 백본을 구성한다고 그랬죠.

근데 이 리스폰더가 체인? 

뭔가 연결되어 있는 것 같죠?


위에서도 말했지만, 앱에서 어떠한 이벤트를 받으면, 이 이벤트를 처리할 대상을 찾기위해서 계속 전달과정을 거칩니다.

어떤 리스폰더가 이 이벤트를 처리하지않으면, 리스폰더 체인을 거쳐 다음 리스폰더로 그 이벤트를 전달하는 것이죠./



이것들이 UIResponder의 리스폰더 체인을 관리해주는 메소드들입니다.

뭔가 많이 본 메소드도 있고, 아닌 메소드도 있네요. 저는 

becomeFirstResponder() resignFirstResponder() 가장 많이 쓰고 있습니당

바로 TextField를 다룰때...다들 많이 쓰시죠?
아 갑자기 생각난거지만..


UIView는 UIResponder를 상속받고 있다는거..아시죠?

UITextField도 UIControl을 상속받고 있지만, 이 UIControl이 UIResponder를 상속받고 있기 때문에... UITextField에서 위 리스폰더 체인 메소드들을 호출할 수 있는 것입니당



becomeFirstResponder()의 정의를 잠깐 보면,
"Asks UIKit to make this object the first responder in its window."

이 객체(becomeFirstResponder()를 호출한 객체겠죠?)를 window의 첫번째 리스폰더로 만들기 위해 UIKit에 요청합니다.
라고 나와있네요. 이걸 UITextField에서 호출하면 키보드가 나왔었죠?
왜 키보드가 나오냐면, UITextField에서 키보드는 객체가 최초 리스폰더가 될 경우에 나타나기 때문입니다. 
다른 객체가 최초 리스폰더가 되면 사라지게 되죠.
resignFirstResponder()도 잠깐 볼까요. window의 최초 리스폰더로서의 상태를 양도(relinquish. 그만두다, 양도하다, 기권하다..등)하도록 요청을 받았음을 알립니다.
그러므로 UITextField에서 resignFirstResponder()를 호출하면 키보드가 사라지는 것이죠. 

출처 : https://gingsoft.com/?p=1348


이것이 리스폰더 체인을 그림으로 나타낸 것인데요, 

이벤트를 처리할 리스폰더를 찾는 순서?라고 생각하시면 같아요.

먼저 왼쪽과 오른쪽이 조금 다른데..왼쪽부터 봅시다.


1. 초기View(이벤트를 최초로 받은 View) 이벤트 또는 메세지를 처리하려고 시도합니다. 이벤트를 처리할 없는경우, 초기View 해당 View superView 이벤트를 전달합니다. 왜냐하면, 초기View viewcontroller view계층에서 최상위view 아니기 때문입니다.


2. superView 이벤트를 처리하려고 시도합니다. superView 이벤트를 처리 없는 경우, View 여전히 View계층에서 최상위View 아니기때문에, 이벤트를 superView(지금 말하는 superView superView) 전달합니다.

3. Viewcontroller view계층 구조에서, 최상위View 이벤트를 처리하려고 시도합니다. 최상위View 이벤트를 처리할 없는 경우, 해당 ViewController 이벤트를 전달합니다.

4. viewController 이벤트를 처리하려고 시도하고, 이벤트처리를 없으면, 이벤트를 window 전달합니다.

5. window객체가 이벤트를 처리 없는 경우, 이벤트는 singleton app object 전달됩니다. 

 (싱글톤 오브젝트는 아직 저도 모르겠는데, UIApplication 나오는 내용입니다.)

6. application 객체가 이벤트를 처리 없는 경우, 이벤트를 삭제합니다.



진짜 체인처럼 이어지죠?

그럼 오른쪽을 봅ㄱ시다.


1. view 최상위View 도달 까지 ViewController View계층 구조 위로 이벤트를 전달합니다.

2. 최상위 View 이벤트를 ViewController 전달합니다.

3. ViewController 이벤트를 최상위View superView 전달합니다. 

1~3단계는 이벤트가 root viewController 도달할 까지 반복됩니다.


4.  root viewController 이벤트를 window 전달합니다.

5. window application객체에 이벤트를 전달합니다. 


언제 왼쪽이 되고...언제 오른쪽이 되는지는 모르겠는데,

중요한건, 이벤트는 전달될 있다는걸 아는것이 가장 중요하다고 생각해요!

내가 관심있는 이벤트는 처리하고, 아닌건 다른 리스폰더로 전달 있는게 가능해지겠네요. 


아무튼..! 재밌네요. HitTest 완벽히 이해하기위해서 공부를 시작했는데..

리스폰더 체인은 말로만 들어봤지 깊게 알지는 못했는데 이번기회에 알게된 기분?

XD

아직 완벽히 알지는 못하겠네요.

아무튼 질문이 있거나 틀린 부분이 있다면 댓글이나 PC화면 오른쪽 하단의 채널서비스를 통해 메세지 주시면 감사하겠씁니당


반응형

'iOS' 카테고리의 다른 글

iOS ) hitTest  (16) 2018.06.13
iOS ) UIApplication  (3) 2018.05.27
iOS ) AVKit과 AVFoundation  (1) 2018.05.13
iOS ) GCD - Dispatch Queue사용법 (2) / DispatchWorkItem, DispatchGroup  (3) 2018.05.01
iOS ) Prioritize Work with Quality of Service Classes  (0) 2018.04.29