swiftswiftuigestureuitapgesturerecognizeruilongpressgesturerecogni

Trigger action when releasing LongPressGesture SwiftUI


I'm trying to trigger the message "pressed" when I release the LongPressGesture inside the minimumDistance but this code instead print out the message as soon as I long press on the Image. How can I solve this?

struct ContentView: View {
    @GestureState private var isDetectingPress = false
    
    var body: some View {
        Image(systemName: "trash")
            .resizable().aspectRatio(contentMode: .fit)
            .frame(width: 100, height: 100)
            .scaleEffect(isDetectingPress ? 0.5 : 1)
            .animation(.easeInOut(duration: 0.2))
            .gesture(LongPressGesture(minimumDuration: 0.01).sequenced(before:DragGesture(minimumDistance: 100).onEnded {_ in
                print("Ended")
            })
                .updating($isDetectingPress) { value, state, _ in
                    switch value {
                    case .second(true, nil):
                        state = true
                        // The message below should be printed when I release the long press
                        print("pressed")
                    case .second(true, _):
                        state = false
                        break
                    default:
                        break
                    }
            })
    }
}

Solution

  • You may try the following:

    struct ContentView: View {
        var body: some View {
            Button(action: {
                print("Pressed")
            }) {
                Image(systemName: "trash")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 100, height: 100)
            }
            .buttonStyle(ScalableButtonStyle())
        }
    }
    
    struct ScalableButtonStyle: ButtonStyle {
        let scaleWhenPressed: CGFloat = 0.75
    
        func makeBody(configuration: Configuration) -> some View {
            configuration.label
                .scaleEffect(configuration.isPressed ? scaleWhenPressed : 1.0)
        }
    }