iOS/SwiftUI

SwiftUI에서의 제스처 우선순위 이해하기: highPriorityGesture와 simultaneousGesture

당근쥬스 2024. 10. 17. 11:11
반응형

SwiftUI는 사용자 인터페이스를 구축하기 위한 강력한 프레임워크로, 제스처 처리에 있어 유연성과 간결함을 제공합니다. 그러나 여러 제스처를 다룰 때 제스처 간의 우선순위와 상호 작용을 이해하는 것은 필수적입니다. 이번 블로그에서는 highPriorityGesturesimultaneousGesture를 중심으로 SwiftUI에서의 제스처 우선순위를 자세히 알아보겠습니다.

 

목차

 

1. SwiftUI의 기본 제스처 처리

2. gesture(_:)의 이해

3. highPriorityGesture(_:)의 동작 방식

4. simultaneousGesture(_:)의 동작 방식

5. 제스처 우선순위의 실제 사례

6. 제스처 충돌 해결 방법

7. 결론

 

1. SwiftUI의 기본 제스처 처리

 

SwiftUI에서 제스처는 사용자의 터치, 스와이프, 핀치 등의 입력을 처리하는 데 사용됩니다. 제스처는 뷰에 직접 추가할 수 있으며, 뷰 계층 구조와 제스처의 종류에 따라 이벤트가 처리됩니다.

 

기본적으로 SwiftUI는 다음과 같은 제스처 우선순위를 가집니다:

 

자식 뷰의 제스처가 부모 뷰의 제스처보다 우선합니다.

여러 제스처가 동일한 뷰에 적용된 경우, 제스처가 추가된 순서에 따라 우선순위가 결정됩니다.

 

하지만 때로는 이 기본 우선순위를 변경해야 할 필요가 있습니다. 이때 highPriorityGesturesimultaneousGesture를 사용하여 제스처의 우선순위를 제어할 수 있습니다.

 

2. gesture(_:)의 이해

 

gesture(_:)는 뷰에 제스처를 추가하는 가장 기본적인 방법입니다. 이 메서드를 사용하면 뷰에 단일 제스처를 추가할 수 있으며, 특별한 우선순위 없이 기본 순서대로 제스처가 처리됩니다.

MyView()
    .gesture(
        TapGesture().onEnded {
            print("뷰가 탭되었습니다.")
        }
    )

위 코드에서는 MyViewTapGesture를 추가하여 뷰가 탭될 때마다 메시지를 출력합니다.

 

3. highPriorityGesture(_:)의 동작 방식

 

highPriorityGesture(_:)는 해당 제스처의 우선순위를 높여 다른 제스처보다 먼저 인식되도록 합니다. 이를 통해 제스처 충돌 시 특정 제스처를 우선적으로 처리할 수 있습니다.

MyView()
    .highPriorityGesture(
        TapGesture().onEnded {
            print("높은 우선순위로 탭 제스처 인식")
        }
    )

 

사용 시점

 

부모 뷰와 자식 뷰에 각각 제스처가 있을 때, 부모 뷰의 제스처를 우선시하고 싶을 때.

특정 제스처가 다른 제스처를 가로채야 하는 경우.

 

주의사항

 

highPriorityGesture를 사용하면 다른 제스처를 가로챌 수 있으므로, 사용자 경험에 영향을 미칠 수 있습니다.

스크롤과 같은 기본 제스처를 방해하지 않도록 주의해야 합니다.

 

4. simultaneousGesture(_:)의 동작 방식

 

simultaneousGesture(_:)는 우선순위와 상관없이 여러 제스처를 동시에 인식하고 처리합니다. 이를 통해 제스처 간의 충돌 없이 모든 제스처 이벤트를 받을 수 있습니다.

MyView()
    .simultaneousGesture(
        TapGesture().onEnded {
            print("동시에 탭 제스처 인식")
        }
    )

 

사용 시점

 

부모 뷰와 자식 뷰의 제스처를 모두 인식하고 처리하고 싶을 때.

여러 제스처가 동시에 인식되어야 하는 경우.

 

주의사항

 

제스처 이벤트가 동시에 호출되므로, 이벤트 처리 로직에서 동시성 문제가 발생하지 않도록 주의해야 합니다.

반응형

5. 제스처 우선순위의 실제 사례

 

상황 예시: ScrollView와 DragGesture

 

ScrollView는 내부적으로 스크롤을 처리하기 위해 DragGesture를 사용합니다. 따라서 ScrollView에 추가로 DragGesture를 적용하면 제스처 충돌이 발생할 수 있습니다.

 

문제점

 

ScrollView에 추가한 DragGestureonChanged 핸들러가 호출되지 않음.

이는 ScrollView의 제스처가 우선하여 개발자가 추가한 제스처가 인식되지 않기 때문입니다.

 

해결 방법 1: simultaneousGesture 사용

ScrollView {
    VStack {
        // 콘텐츠 뷰
    }
    .simultaneousGesture(
        DragGesture().onChanged { _ in
            print("사용자 정의 드래그 제스처 인식")
        }
    )
}

simultaneousGesture를 사용하여 ScrollView의 스크롤 제스처와 개발자의 DragGesture동시에 인식하도록 합니다.

 

해결 방법 2: highPriorityGesture 사용

ScrollView {
    VStack {
        // 콘텐츠 뷰
    }
    .highPriorityGesture(
        DragGesture().onChanged { _ in
            print("우선순위 높은 드래그 제스처 인식")
        }
    )
}

highPriorityGesture를 사용하여 개발자의 제스처를 우선적으로 인식하도록 합니다.

하지만 이 경우 스크롤 동작이 방해받을 수 있으므로 주의가 필요합니다.

 

6. 제스처 충돌 해결 방법

 

simultaneousGesture를 통한 동시 인식

 

simultaneousGesture는 제스처를 동시에 처리하므로, 스크롤 동작과 추가한 제스처가 모두 정상적으로 동작합니다.

ScrollView {
    VStack {
        // 콘텐츠 뷰
    }
    .simultaneousGesture(
        DragGesture().onChanged { _ in
            hideKeyboard()
        }
    )
}

 

위 코드에서는 사용자가 스크롤할 때 키보드를 숨기면서도 스크롤 동작은 그대로 유지됩니다.

 

highPriorityGesture의 신중한 사용

 

highPriorityGesture는 다른 제스처를 가로챌 수 있으므로, 사용자 경험에 미치는 영향을 고려하여 신중하게 사용해야 합니다.

 

7. 결론

 

SwiftUI에서 제스처의 우선순위와 이벤트 처리는 복잡할 수 있지만, highPriorityGesturesimultaneousGesture를 적절히 활용하면 원하는 동작을 구현할 수 있습니다.

 

highPriorityGesture: 특정 제스처를 우선적으로 처리하고 싶을 때 사용.

simultaneousGesture: 여러 제스처를 동시에 인식하고 싶을 때 사용.

 

제스처를 적용할 때는 사용자 경험을 최우선으로 고려해야 하며, 제스처 간의 상호 작용과 우선순위를 이해하고 적용해야 합니다.

 

참고 자료

 

Apple Developer Documentation - gesture(_:including:)

Apple Developer Documentation - highPriorityGesture(_:including:)

Apple Developer Documentation - simultaneousGesture(_:including:)

 

SwiftUI에서 제스처를 다룰 때 발생하는 문제나 궁금증이 있다면 댓글로 남겨주세요! 함께 해결해 나가겠습니다.

반응형