저번 글에 언급해둔바와 같이 이번엔 UIResponder에 대해 알아볼 것이다.
공식문서를 한 번 확인해보자 !
이벤트 응답 및 처리를 위한 추상 인터페이스라고 한다.
이 UIResponder
인스턴스가 바로 저번 글에서 주구장창 나오던 responder 객체이다.
이벤트가 발생하면 저번 글에서 봤듯이 UIKit이 지정한(혹은 개발자가 직접 지정한) responder 객체로 이벤트를 보내서 처리하게된다.
이 responder 객체가 이벤트를 처리하기위해서는 적절한 메소드들을 오버라이딩하여 처리해줘야한다. 예를 들어 Touch 이벤트가 일어나면 touchesBegan(_:with:)
, touchesMoved(_:with:)
, touchesEnded(_:with:)
, touchesCancelled(_:with:)
와 같은 메소드들 오버라이딩해서 터치이벤트를 처리할 수 있는 것이다.
responder의 역할은 이벤트를 처리하는 것이 다가 아니다. 이벤트 처리 뿐만 아니라 이벤트를 해당 responder 객체에서 처리하지 못했을 때, responder chain에 명시된 다음 responder 객체로 넘겨주는 일까지 해준다.
전 글에서 봤듯 responder chain은 UIKit이 동적으로 관리하지만 개발자가 따로 커스텀할 수도 있다는 사실 ~
Responder는 기본적으로는 UIEvent
를 처리하지만, input view를 통해 custom input을 발생시키는 것도 가능하다. 시스템 키보드가 바로 대표적인 input view의 예시이다. 유저가 UITextField
나 UITextView
를 탭하면, 뷰는 first responder가 되고 그들의 input view인 시스템 키보드를 화면에 띄워준다.
여기까지 UIResponder
의 역할에 대해 알아보았다. 정리를 해보면 아래와 같다.
UIResponder
는 적절한 메소드를 오버라이딩하여 이벤트를 처리한다.- 이벤트를 처리하지 않았을 경우, responder chain을 통해 다음 responder 객체로 이벤트를 넘겨준다.
- custom input view를 띄울 수 있다.
Responder의 역할들을 알아보았으니 UIResponder 클래스에 존재하는 주요 메소드들과 프로퍼티들을 쓱 ~ 훑어보자 ~
주요 Methods 및 Properties
touch 이벤트가 발생했을 때 활용할 수 있는 메소드들
press 이벤트가 발생했을 때 활용할 수 있는 메소드들
문득 touch랑 press 이벤트가 어떤 차이가 있나.. 궁금해서 실험을 해봤다.
touch vs press
문서를 보면 press 이벤트를 물리적인 버튼에 대한 이벤트라길래 난 소리 조절버튼이나 전원버튼을 말하는줄 알았다.
메인이 되는 VC에 아래와 같이 메소드를 오버라이딩하여 사용해봤는데 음량 버튼을 눌러도 아무런 반응이 없었다.. 화면을 길게 눌러봐도 touchEvent만 반응했다..
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
print("view touch began")
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
print("view touch end")
}
override func pressesBegan(_ presses: Set<UIPress>, with event: UIPressesEvent?) {
presses.forEach { press in
print(press.key)
}
}
override func pressesEnded(_ presses: Set<UIPress>, with event: UIPressesEvent?) {
print("view press ended")
}
}
뭐 하나 한번에 되는 법이 없지 ^^ ~
여기저기 찾아보니 저 physical button이 키보드를 나타내는 것이라는 정보를 얻었다. 그리고 키보드를 눌렀더니 아래와 같이 반응이 왔다 !
이것저것 눌러봤는디, press는 키보드 관련 이벤트를 말하는 것 같았다.
UIEvent 관련해서는 따로 글을 정리해봐야겠다..
잠깐 딴길로 샜는데.. 이어서 UIResponder의 프로퍼티들과 메소드들을 확인해보자 ^^;; (아 이래서 내 글이 가독성이 진짜 엄청 떨어지는 것 같다..)
responder chain을 관리할 수 있는 메소드 및 프로퍼티들
여기서 하나의 팁(?)은
UITextField
와UITextView
는 위에서 잠시 얘기한 바와 같이 input view가 시스템 키보드로 설정되어있다. 그래서 해당 객체를 터치하면UITextField
나UITextView
가 first responder가 되면서 input view(키보드)가 화면에 나타나게 된다. 이 input view를 사라지게 하고싶다면 반대로 first responder로 되어있는 것을resignFirstResponder
를 활용하여 해제해주면 된다 !보다 직관적으로 얘기해보자면, 만약 내가 키보드가 아닌 다른 뷰를 터치해서 키보드를 내리고싶다면, 아래 코드와 같이 해당 뷰의
touchsBegan()
을 오버라이딩하여UITextField
(혹은UITextView
)의resignFirstResponder
를 호출하면 된다.class ViewController: UIViewController { let text: UITextField = { let text = UITextField(frame: CGRect(x: 200, y: 400, width: 180, height: 80)) text.becomeFirstResponder() return text }() override func viewDidLoad() { super.viewDidLoad() view.addSubview(text) } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { print("view touch began") text.resignFirstResponder() } }
UIResponder
를 알아보면서 신기했던점은 keyboard관련 프로퍼티들이 UITextField
나 UITextView
에 존재하는줄 알았는데 얘네들이 UIResponder
에 있었다는게 너무 신기했다.
중간에.. 주인장의 귀찮음 이슈로 메소드들을 냅다 캡처해서 박은점.. 반성하며.. 이번 글은 여기서 마무리하겠다 ~
참고자료
'iOS' 카테고리의 다른 글
[iOS] 이벤트 처리 (1) | 2024.09.15 |
---|---|
[iOS] Container view controller (0) | 2024.08.25 |