iosswiftswiftuigesture

How to detect whether a SwiftUI gesture failed?


In the following example if only the long press will be performed, there is (apparently) no (built-in) way to find out that the drag gesture had failed (if I just lift my finger off the screen for example)

Is there a way to detect wether the second gesture had failed or hasn't been started?

.gesture(
    LongPressGesture()
        .onEnded { _ in
            // First gesture completed ...
        }
        .sequenced(
            before:
                DragGesture()
                    .onEnded { gesture in
                        // Second gesture ended (not called if it has failed) ...
                    }
        )
        .onEnded { _ in
           // Only called if both gestures succeed...
        }
)

Solution

  • You can use exclusively(before:) to achieve this effect. If you have A.exclusively(before: B), then SwiftUI will try to recognise gesture B only if A fails.

    In this case, A would be the long press + drag gesture, and B would be just the long press gesture. If B is triggered, that means there is a long press but A failed, which implies that it is the drag gesture that failed.

    .gesture(
        LongPressGesture()
            .onEnded { _ in
                print("Long press completed")
            }
            .sequenced(
                before: DragGesture()
                    .onEnded { gesture in
                        print("Drag completed")
                    }
            )
            .onEnded { x in
                print("Both completed")
            }
            .exclusively(
                before: LongPressGesture()
                    .onEnded { _ in print("Drag failed") }
            )
    )