SwiftUI - how to detect long press on Button?

Viewed 3061

I have a Button where when it gets pressed, it performs some actions. But I would like to modify the same Button to detect a longer press, and perform a different set of processes. How do I modify this code to detect a long press?

Button(action: {
              // some processes

            }) {
              Image(systemName: "circle")
                .font(.headline)
                .opacity(0.4)

            }
3 Answers

Here is possible variant (tested with Xcode 11.2 / iSO 13.2).

Button("Demo") {
    print("> tap")
}
.simultaneousGesture(LongPressGesture().onEnded { _ in
    print(">> long press")
})

Daniel Wood's comment is correct in both statements. First, it is the cleanest solution. For the second, there is a straightforward workaround.

struct ContentView: View {
  @State private var didLongPress = false

  var body: some View {
    Button("Demo") {
      if self.didLongPress {
        self.didLongPress = false
          doLongPressThing()
      } else {
          doTapThing()
      }
    }.simultaneousGesture(
      LongPressGesture().onEnded { _ in self.didLongPress = true }
    )
  }
}

This way you can also recognize a long press on a button and distinguish it from a simple tap gesture:

        Button(action: {}) {
            Text("Push")
        }
        .simultaneousGesture(TapGesture().onEnded { _ in
            print("simultaneousGesture TapGesture")
        })
        .simultaneousGesture(LongPressGesture().onEnded { _ in
            print("simultaneousGesture LongPressGesture")
        })
Related