Search code examples
swiftuigesture-recognition

How to run code when swiftui gesture recognizers begin


SwiftUI MagnificationGesture and DragGesture have .onChanged and .onEnded APIs but nothing to check when the gesture started like in UIKit. Couple ways I thought to do it:

  • .$gestureStarted bool in onChanged and then set it back to false in .onEnded
  • use a gesture sequence with tap.

Am I missing some preferred way to do this? Seems like a pretty natural thing to want to check.


Solution

  • There is special @GestureState, which can be used for such purpose. So, here is possible approach

    struct TestGestureBegin: View {
    
        enum Progress {
            case inactive
            case started
            case changed
        }
        @GestureState private var gestureState: Progress = .inactive // initial & reset value
    
        var body: some View {
            VStack {
                Text("Drag over me!")
            }
            .frame(width: 200, height: 200)
            .background(Color.yellow)
            .gesture(DragGesture(minimumDistance: 0)
                .updating($gestureState, body: { (value, state, transaction) in
                    switch state {
                        case .inactive:
                            state = .started
                            print("> started")
                        case .started:
                            state = .changed
                            print(">> just changed")
                        case .changed:
                            print(">>> changing")
                    }
                })
                .onEnded { value in
                    print("x ended")
                }
            )
        }
    }