1

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
                    }
            })
    }
}
xmetal
  • 681
  • 6
  • 16
  • It is not clear what do you try to achieve? And why do you need `minimumDistance: 100`? – Asperi Aug 01 '20 at 10:59
  • The `DragGesture(minimumDistance: 0)` was needed to keep state till you keep toching but it called onEnded right after release finger (your pressed case), but now it waits for dragging at 100 and failed so no onEnded. Would you explain the behavior instead? – Asperi Aug 01 '20 at 11:04
  • I basically need to perform an action when LongPressGesture in ended but inside the minimum distance. If I go beyode the limit distance then I don't need to perform the action anymore. Let's assume I have this "trash" Image and I press on it but later i realized I don't need to release the finger on it to perform the action...I would simply move my finger out of that image and expect not to perform the action I was expecting – xmetal Aug 01 '20 at 11:04
  • 1
    @xmetal Why don't you use a `Button` instead (with an Image inside)? – pawello2222 Aug 01 '20 at 11:06
  • 1
    It is really a standard button behavior – Asperi Aug 01 '20 at 11:07
  • @pawello2222 Then how can I make it work with a button instead? I think you understood what i want to acheive but since I don't know how to make it with an image it would be the same for a button I guess – xmetal Aug 01 '20 at 11:07
  • @Asperi is it really? then I just need to scale the image inside a button and if I move my finger out it ends the gesture? – xmetal Aug 01 '20 at 11:09

1 Answers1

2

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)
    }
}
pawello2222
  • 46,897
  • 22
  • 145
  • 209