SwiftUI는 제스처 인식 기능을 통해 다양한 사용자 인터랙션을 처리할 수 있는 강력한 도구, 메서드를 제공합니다. 그 중 onTapGesture는 가장 많이 사용하는 제스처 중 하나로, 뷰를 터치했을 때 특정 동작을 수행하는 방식으로 사용됩니다. 하지만 onTapGesture를 여러 개 추가하거나, 이미 제스처가 있는 뷰에 다시 추가할 때 예상치 못한 결과를 발생시킬 수 있습니다.
이 글에서는 이러한 문제를 해결하는 방법과 함께, SwiftUI에서 제공하는 simultaneousGesture의 활용 방법을 자세히 살펴보겠습니다.
SwiftUI 제스처의 기본 동작
Button {
print("Action")
} label: {
Text("Action")
}
.onTapGesture {
print("Action2")
}
우선 다음과 같이 Button Action과 .onTapGesture를 함께 사용했을 경우 결과는 다음과 같습니다.
이 코드를 실행하면 버튼의 액션이 실행되면서 print(“Action”)이 출력되지만, 그 밑의 제스처가 제대로 동작하지 않는 것을 볼 수 있습니다. Button의 액션이 제스처보다 우선적으로 처리되기 때문에 후속 액션은 무시되는 상황이 발생하게 됩니다.
다음으로 Text에 여러 개의 제스처를 사용한 예시를 살펴보겠습니다.
Text("Action")
.onTapGesture {
print("Action1")
}
.onTapGesture {
print("Action2")
}
.onTapGesture {
print("Action3")
}
위 코드에서도 첫 번째 제스처만 인식되고, 나머지는 동작하지 않는 것을 확인할 수 있습니다. 즉, 여러 개의 제스처를 중복해서 사용하는 경우 하나의 제스처만 처리되고, 나머지 제스처는 무시됩니다. 이러한 현상은 제스처가 서로 우선순위를 가지며 충돌하기 때문에 발생합니다.
simultaneousGesture란?
@frozen
struct SimultaneousGesture<First, Second> where First : Gesture, Second : Gesture
이런 문제를 해결하기 위해서 SwiftUI는 simultaneousGesture를 제공합니다. 해당 메서드는 두 개의 제스처를 동시에 인식하고 처리할 수 있는 기능을 제공하는 제스처 컨테이너입니다. 이 제스처는 두 개의 하위 제스처를 포함하여 두 제스처가 순서에 상관없이 동시에 발생할 수 있게 해줍니다. 한 제스처가 우선하거나 뒤처지지 않고 동시에 처리할 수 있게 해줍니다.
이제 위에서 제기한 문제를 simultaneousGesture로 해결하는 방법을 살펴보겠습니다. 앞서 본 Button과 onTapGesture가 함께 동작하지 않는 문제를 이 메서드로 해결해 보겠습니다.
Text("Action")
.simultaneousGesture(
TapGesture().onEnded {
print("Action1")
}
)
.simultaneousGesture(
TapGesture().onEnded {
print("Action2")
}
)
.simultaneousGesture(
TapGesture().onEnded {
print("Action3")
}
)
Button {
print("Action")
} label: {
Text("Action")
}
.simultaneousGesture(
TapGesture().onEnded {
print("Action2")
}
)
.simultaneousGesture(
TapGesture().onEnded {
print("Action3")
}
)
.simultaneousGesture(
TapGesture().onEnded {
print("Action4")
}
)
이 코드를 통해 이제 Text 뷰에 적용된 세 개의 제스처가 모두 동작하게 됩니다. 각 제스처는 동시에 처리되며, 서로의 동작을 방해하지 않습니다.
simultaneoutGesture는 다음과 같은 상황에서 매우 유용하게 사용할 수 있습니다.
– 멀티터치 제스처: 사용자가 화면의 여러 곳을 동시에 터치하는 경우 두 개 이상의 제스처를 동시 처리할 때 사용됩니다. 예를 들어, 두 손가락으로 화면을 동시에 탭하는 동작을 인식하게 만들 수 있습니다.
– 복잡 제스처: 동일한 뷰에서 여러 제스처를 한꺼번에 처리하고자 할 때 적합합니다. 예를 들어, 화면을 탭하면서 동시에 스와이프하는 동작을 처리하고 싶을 때 사용할 수 있습니다.
– 기존 코드를 수정하지 않고 기능 추가: 기존 코드에 대한 수정 없이 print() 문을 추가하거나 GA를 달려고 할 때 유용하게 사용될 수 있습니다.