iOS 응용 (swift)
[iOS - swift] 1. touch indicator 구현 방법 - 기초 개념 sendEvent(_:), UIEvent (allTouches, UITouch)
jake-kim
2023. 11. 11. 01:53
1. touch indicator 구현 방법 - 기초 개념 sendEvent(_:), UIEvent (allTouches, UITouch, phase)
2. touch indicator 구현 방법 - DebugTouchesWindow, Touch Indicator

이벤트 처리 방식
- 터치 이벤트가 발생하면 UIApplicationDelegate부터 시작하여 터치된 뷰를 탐색
- 주의) 애플에서 보여주는 이미지는 아래처럼 되어있어서 얼핏 터치 이벤트 전달 과정이 가장 위에 깔린 뷰부터라고 오해할 수 있지만 잘못된 개념

- 실제로는 UIWindow가 먼저 받아서 이 위에 깔린 뷰에게 전달하고 위에 깔린 뷰에 responder 탐색하는것
ex) 아래에서 알아볼 UIWindow의 sendEvent가 가장 먼저 호출되고 ViewController 이벤트가 호출

sendEvent(_:) 개념
- UIApplication에 있는 메서드
- responder chain의 시작점이며, 앱 터치가 발생하면 출발점을 의미

- UIWindow를 서브클래싱하여 사용이 가능
class MyWindow: UIWindow {
override func sendEvent(_ event: UIEvent) {
print("sendEvent in window")
super.sendEvent(event)
}
}
UIEvent 개념
- 터치, pan, long press 등 이벤트에대한 정보를 가지고 있는 모델

- 대표적으로 UIWindow의 sendEvent에서 인수로 들어오는 타입
class MyWindow: UIWindow {
override func sendEvent(_ event: UIEvent) {
print("sendEvent in window")
super.sendEvent(event)
}
}
- 이 정보에는 이벤트와 관련된 touches, 시간, 유형 파악이 가능

- 모든 touch를 조사하여 이벤트가 시작되었는지 종료되었는지 began, end 파악도 가능
- 여기서 특정 기능을 수행한 후 super.sendEvent(event)를 호출하면 이벤트가 시작되거나 종료될 때 특별한 행동 수행이 가능
class MyWindow: UIWindow {
open override func sendEvent(_ event: UIEvent) {
if let allTouches = event.allTouches {
allTouches.forEach { touch in
switch touch.phase {
case .began:
print("began")
case .ended, .cancelled:
print("end")
default:
// .moved, .stationary, .regionEntered, .regionMoved, .regionExited
break
}
}
}
super.sendEvent(event)
}
}
정리
- response 처리는 UIWindow에서 sendEvent가 출발점이며, 이 메서드가 실행된 후 터치가 된 뷰의 touch가 인식됨
- sendEvent(_:)에서 이벤트를 가로채서 특정 작업이 가능
- 이때 터치되는 영역에 뷰를 넣어서 touch indicator 구현이 가능 (다음 포스팅 글에서 계속)

* 전체 코드: https://github.com/JK0369/ExUITouch
* 참고
https://developer.apple.com/documentation/uikit/uievent
https://developer.apple.com/documentation/uikit/uiapplication/1623043-sendevent