
SwiftUI를 사용해서 앱을 만들 때, .onTapGesture(),
.gesture()
등 기본적인 제스처들을 통해 다양한 사용자 상호작용을 구현할 수 있다. 버튼 요소도 많이 쓰이지만, 제스처 속성도 상당히 많이 쓰이는 코드 중에 하나다.
보통 제스처를 통해 한 번 탭 했을 때의 동작을 정의한다던가. 아래와 같이 길게 화면의 요소를 탭 했을 때의 동작을 정의한다.
우선 간단하게 SwiftUI에서 .gesture()
의 코드를 사용하는 예시를 보자.
SwiftU의 기본 제스처 사용법
1. TapGesture: 화면을 탭했을 때 동작을 정의
.onTapGesture(count: 2) {
print("더블 탭 감지됨")
}
2. LongPressGesture: 길게 누르는 동작을 정의
.gesture(
LongPressGesture(minimumDuration: 1.0)
.onEnded { _ in
isPressed.toggle()
}
)
3. DragGesture: 드래그 동작을 정의
.gesture(
DragGesture()
.onChanged { value in
offset = value.translation
}
.onEnded { value in
withAnimation(.spring()) {
offset = .zero
}
}
)
그런데, List
안에서와 ScrollView
안에서는 일반 SwiftUI 제스처 동작이 동작하지 않는다.
아무래도 List
나 ScrollView
의 기본 동작에 제스처가 들어있기 때문에 다른 동작을 무시하는 것 같다. 왜냐하면 SwiftUI에서는 제스처 간에 우선순위가 있기 때문이다. 이로 인해 충돌이 발생할 수 있다.
이럴 때 SwiftUI에 이미 사용할 수 있는 제스처가 정의되어 있다.
바로 simultaneousGesture
이다.
SwiftUI simultaneousGesture 사용 방법
.simultaneousGesture(
TapGesture()
.onEnded {
tapCount += 1
print("Tapped \(tapCount) times!")
}
)
위 코드 예시와 같이 SwiftUI에서 .gesture
가 아닌 .simultaneousGesture
로 사용하면 제스처를 동작하게 할 수 있다. 기본 제스처와 사용자 정의 제스처가 동시에 동작한다.
단순히 그냥 제스처를 넣는것 뿐만 아니라 제스처와 애니메이션을 결합하여 더 풍부한 사용자 경험을 제공할 수 있다.
또는 List 내에서 항목을 터치했을 때 상세 정보로 이동하면서, 길게 눌렀을 때는 컨텍스트 메뉴를 표시하는 패턴을 구현할 수도 있다.
아니면, 리스트 안에서 navigationLink
를 넣을 때 동시에 애니메이션 효과나 햅틱 피드백 효과를 주고 싶을 수 있다. 그럴 때 일반 제스처를 이용하면 navigationLink
의 우선순위 때문에 동작하지 않지만 simultaneousGesture
를 사용하여 애니메이션이나 햅틱 피드백 효과를 줄 수 있다.
simultaneous의 뜻을 살펴보자.

일반 제스처가 아닌 동시에 일어나는, 동시의, 동시에 존재하는 프레임워크에 미리 정의되어있는 SwiftUI 제스처다.
그래서 다른 기본적인 제스처나 내장된 제스처와 함께 사용할 때에도 동작이 무시되지 않고 잘 동작한다.
SwiftUI 제스처를 마스터하면 사용자에게 더 직관적이고 매력적인 앱 경험을 제공할 수 있다.
다만 simultaneousGesture
를
남발하면 여러 동작이 너무 동시에 일어나는 바람에 사용자가 가로로 스크롤 하고 싶었지만 세로로 스크롤도 동시에 되어버리는 일이 발생하여 사용자의 경험을 해치니 꼭 필요한 곳에만 사용하는 것이 좋다.