SwiftUI) 여러 액션 동시에 처리하기

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를 달려고 할 때 유용하게 사용될 수 있습니다.

Leave a Comment