UIKit의 제스처
- UIKit
- Swift
🤔 제스처(Gesture)란?
Handling UIKit gestures | Apple Developer Documentation
Swift/UIKit에서 말하는 Gesture는 사용자가 화면을 손가락으로 움직여서 발생시키는 일련의 모든 동작을 추상화한 개념입니다.
단순한 터치만 말하는 것이 아닌 터치 패턴 자체를 제스처라고 말합니다.
- 짧게 누르기
- 길게 누르기
- 두 손가락으로 벌리기
- 한 손사락으로 드래그하기 등
결론적으로 다양한 터치 이벤트들을 패턴 단위로 묶어 추상화한 개념이 제스처라고 할 수 있습니다.
iOS는 이러한 제스처를 자동으로 인식하고 다룰 수 있도록 UIGestureRecognizer를 제공합니다.
UIGestureRecognzier
UIGestureRecognizer | Apple Developer Documentation

iOS의 제스처 인식기에는 2가지 종류가 존재합니다.
- 불연속 제스처 인식기
- 이벤트를 인식한 후 Action을
한 번만호출하는 것을 말합니다. UITapGestureRecognizer가 대표적인 불연속 제스처 인식기입니다.- 쉽게 비유를 해보면 불연속 제스처는
버튼과 같다고 생각하면 될 것 같습니다. - 사용자는 한 번만 클릭하면 동작이 끝납니다.
- 대표적으로 탭(한 번/두 번 처리)이나 롱프레스(길게 눌렀다 땔 때 한 번만 인식)이 있습니다.
- 즉, 사용자가 무엇을 하던
결과는 오직 한 번만 발생하는 것을 말합니다.
- 연속 제스처 인식기
- 최초 이벤트 인식 후 이벤트의 변화를 추적하며 Action을 변화에 맞춰 호출하는 것을 말합니다.
UIPanGestureRecognizer가 대표적인 연속 제스처 인식기입니다.- 쉽게 비유를 해보면 연속 제스처는 다이얼을 돌리는 것과 같습니다.
- 손가락이 움직이는 동안 값은
계속 바뀌고 이벤트가 연속적으로 발생합니다. - 대표적으로 팬(드래그), 핀치(확대/축소), 로테이션(회전)이 있습니다.
- 즉, 사용자가 제스처를
유지하는 동안 현재 상태를 계속 추적하는 것을 말합니다.
앱에 제스처 인식기를 추가하는 방법은 크게 2가지로 나눌 수 있습니다.
- IB로 구현하기
- 스토리보드에서
Gesture Recognizer를 원하는 View 위에 올립니다. - Action을 구현합니다.
- Action과 제스처 감지기를 연결합니다.
- 코드로 구현하기
- 탭의 제스처를 감지하고 싶은 View에서
addGestureRecognizer(_:)를 호출하여 연결할 수 있습니다. - https://developer.apple.com/documentation/uikit/uiview/addgesturerecognizer(_:)
_
UIButton_의 경우 오직버튼객체에 특화된 이벤트를 다룰 수 있지만Gesture recognizer를 사용할 경우 그 어떤 View에서도 1개 혹은 N개의 제스처에 대한 처리를 진행할 수 있습니다!
📌 UIKit에서 지원하는 제스처의 종류
https://developer.apple.com/documentation/uikit/uigesturerecognizer
제스처 인식기의 서브 클래스로 제공되는 다양한 제스처는 아래와 같이 정리할 수 있습니다.
불연속(Discrete) 제스처
불연속 제스처는 한 번만 인식하고 끝나는 동작을 의미합니다.
- UITapGestureRecognizer
- 탭(한 번 누르기, 두 번 누르기 등) 제스처 인식
- https://developer.apple.com/documentation/uikit/uitapgesturerecognizer
- UISwipeGestureRecognizer
- 화면을 한 방향(상, 하, 좌, 우)로 빠르게 스와이프하는 제스처 인식
- https://developer.apple.com/documentation/uikit/uiswipegesturerecognizer
연속(Continuous) 제스처
연속 제스처는 제스처가 진행되는 동안 상태가 계속 업데이트 되는 동작을 의미합니다.
- UIPinchGestureRecognizer
- 핀치(손가락 두 개로 확대/축소) 제스처 인식
- https://developer.apple.com/documentation/uikit/uipinchgesturerecognizer
- UIRotationGestureRecognizer
- 회전 제스처 인식
- https://developer.apple.com/documentation/uikit/uirotationgesturerecognizer
- UIPanGestureRecognizer
- 드래그(손가락으로 끌기) 제스처 인식
- https://developer.apple.com/documentation/uikit/uipangesturerecognizer
- UIScreenEdgePanGestureRecognizer
- 화면의 가장자리(edge)에서 시작해 끌어내리는 드래그(pan) 제스처 인식
- https://developer.apple.com/documentation/uikit/uiscreenedgepangesturerecognizer
- UILongPressGestureRecognizer
- 길게 누르는 제스처 인식
- https://developer.apple.com/documentation/uikit/uilongpressgesturerecognizer
- UIHoverGestureRecognizer (iPadOS, macOS Catalyst 에서 많이 사용)
- 포인터(애플 펜슬, 마우스/트랙패드 포인터)가 View 위를 지나갈 때(Hover)의 제스처 인식
- https://developer.apple.com/documentation/uikit/uihovergesturerecognizer
💻 제스처 추가해보기
대표적인 불연속 제스처인 탭 제스처를 추가해보겠습니다.
탭 제스처를 추가하기 위해 UITapGestureRecognizer를 생성하여 원하는 View에 할당합니다.
아래 코드는 ViewController에게 탭 제스처를 할당하는 코드입니다.
let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
view.addGestureRecognizer(tap)
@objc func handleTap(_ sender: UITapGestureRecognizer) {
logger.debug("탭 제스처가 감지되었습니다.")
}

- 제스처 인식기를 View에 연결하면 해당 View와 모든 하위 View에 정의한 터치를 수신하게 됩니다.
- 이때, View는 제스처 인식기에 대한 강한 참조를 설정한다고 합니다!
- The view establishes a strong reference to the gesture recognizer.
- 만약, 제스처가 인식되지 않는 경우 View의
isUserInteractionEnabled속성이 활성화 되어있는지 확인해보세요! isUserInteractionEnabled는 사용자 이벤트를 무시하고 이벤트 대기열에서 제거할지의 여부를 묻는 속성값입니다.- 기본값은 true이지만 false로 설정된다면 View에 적용되는 모든 터치, 누르기, 키보드 및 포커스 이벤트가 무시됩니다!
- ⭐ 만약에 애니메이션이 실행된다면
isUserInteractionEnabled의 속성값과 관계없이 모든 View에 대한 사용자 상호작용이 일시적으로 비활성화되기 때문에 제스처 또한 동작하지 않습니다. - 그럴때는
allowUserInteraction을 따로 지정하여isUserInteractionEnabled의 동작 자체를 비활성화 시켜야합니다!
During an animation, user interactions are temporarily disabled for all views involved in the animation, regardless of the value in this property. You can disable this behavior by specifying the
allowUserInteractionoption when configuring the animation.
Tap Gesture 처리 팁
- 만약, 여러 제스처를 동시에 처리해야한다면
UIGestureRecognizerDelegate를 채택하여 N개 이상의 제스처 동시 처리나 우선 순위 등을 제어할 수 있습니다. - 하나의 뷰에서 여러 제스처 인식기를 중첩해서 사용할 수 있습니다.
- View에 제스처 인식기를 설정한 경우 강한 참조로 연결됩니다.
- 스토리보드가 아닌
addGestureRecognizer(_:)메서드로 뷰와 관계를 갖는 제스처 인식기는 View의 Responder Chain에 속하지 않습니다. - 해당 개념은 시간이 날 때 정리하고자 합니다.
- 우선, Responder Chain에 대해 너무 잘 정리된 아티클 하나와 공식 문서를 공유드립니다.
Using responders and the responder chain to handle events | Apple Developer Documentation