How to achieve UIKit's "touch down" in SwiftUI?

I want my button to fire when the finger touches the button, not when the finger leaves the button.

A common answer I see on StackOverflow is to use a DragGesture and set minimumDistance to 0. This does trigger the button when the finger touches the button. However, when the finger is pressed down, if I move my finger even just a little bit, the button would get triggered again, which not something that I want. I want the button to fire only when the finger first touches the button, but not when the finger drags the button.

How can I achieve this touch down behavior in SwiftUI?

Thanks in advance.

This isn't an obvious thing to do, but if you play around with the way Button is designed you find out that it uses either PrimitiveButtonStyle or ButtonStyle protocols.

I would probably go with PrimitiveButtonStyle and implement a custom style for your button.

In the end you will have something like this:

Button(...)
  .buttonStyle(MyButtonStyle(/* here you can have expose anything you want */))

This approach allows you to create buttons with custom styles that implement custom gestures.

Here is a quick prototype, but it looses the default button Style.

struct MyButtonStyle: PrimitiveButtonStyle {
  func makeBody(configuration: Configuration) -> some View {
    configuration
      .label
      .onLongPressGesture(
        minimumDuration: 0,
        perform: configuration.trigger
      )
  }
}

struct ContentView: View {
  var body: some View {
    VStack {
      Button("A") {
        print("A pressed")
      }
      Button
        .init("B") {
          print("B pressed")
        }
        .buttonStyle(MyButtonStyle())
    }
  }
}
3 Likes

YOU ARE A LIFE SAVER!
It worked! Can't thank you enough!!!

1 Like
Terms of Service

Privacy Policy

Cookie Policy