title: Capture touchDown location of onLongPressGesture in swiftUI?
body: <p>I'm trying to implement a custom context menu that will appear after a long press at the location the user touched. I have been unable to find a way to capture the XY location of a touch down event for onLongPressGesture.</p>
  <p>This is where I started</p>
  <pre><code>struct ExampleView: View {
      @State var showCustomContextMenu = false
      @State var longPressLocation = CGPoint.zero
      
      var body: some View {
          Rectangle()
              .foregroundColor(Color.green)
              .frame(width: 100.0, height: 100.0)
              .onLongPressGesture {
                  print(&quot;OnLongPressGesture&quot;)
                  self.showCustomContextMenu = true
              }
              .overlay(
                  Rectangle()
                      .foregroundColor(Color.red)
                      .frame(width: 50.0, height: 50.0)
                      .position(longPressLocation) // &lt;----- this is what I need to capture.
                      .opacity( (showCustomContextMenu) ? 1 : 0 )
          )
      }
  }
  </code></pre>
  <p>After looking at this question (and the other SO questions linked in the answer) I tried the following.</p>
  <p><a href="https://stackoverflow.com/questions/58784684/how-do-you-detect-a-swiftui-touchdown-event-with-no-movement-or-duration?noredirect=1&amp;lq=1">How do you detect a SwiftUI touchDown event with no movement or duration?</a></p>
  <pre><code>struct ExampleView: View {
      @State var showCustomContextMenu = false
      @State var longPressLocation = CGPoint.zero
      
      var body: some View {
          ZStack{
              Rectangle()
                  .foregroundColor(Color.green)
                  .frame(width: 100.0, height: 100.0)
                  .onLongPressGesture {
                      print(&quot;OnLongPressGesture&quot;)
                      self.showCustomContextMenu = true
                  }
                  .overlay(
                      Rectangle()
                          .foregroundColor(Color.red)
                          .frame(width: 50.0, height: 50.0)
                          .position(longPressLocation)
                          .opacity( (showCustomContextMenu) ? 1 : 0 )
              )
              TapView { point in
                  self.longPressLocation = point
                  print(&quot;Point: \(point)&quot;)
              }.background(Color.gray).opacity(0.5)
          }
      }
  }
  
  struct TapView: UIViewRepresentable {
      var tappedCallback: ((CGPoint) -&gt; Void)
  
      func makeUIView(context: UIViewRepresentableContext&lt;TapView&gt;) -&gt; TapView.UIViewType {
          let v = UIView(frame: .zero)
          let gesture = SingleTouchDownGestureRecognizer(target: context.coordinator,
                                                         action: #selector(Coordinator.tapped))
          v.addGestureRecognizer(gesture)
          return v
      }
  
      class Coordinator: NSObject {
          var tappedCallback: ((CGPoint) -&gt; Void)
  
          init(tappedCallback: @escaping ((CGPoint) -&gt; Void)) {
              self.tappedCallback = tappedCallback
          }
  
          @objc func tapped(gesture:UITapGestureRecognizer) {
              self.tappedCallback(gesture.location(in: gesture.view))
          }
      }
  
      func makeCoordinator() -&gt; TapView.Coordinator {
          return Coordinator(tappedCallback:self.tappedCallback)
      }
  
      func updateUIView(_ uiView: UIView,
                        context: UIViewRepresentableContext&lt;TapView&gt;) {
      }
  }
  
  class SingleTouchDownGestureRecognizer: UIGestureRecognizer {
      override func touchesBegan(_ touches: Set&lt;UITouch&gt;, with event: UIEvent) {
          if self.state == .possible {
              self.state = .recognized
          }
      }
      override func touchesMoved(_ touches: Set&lt;UITouch&gt;, with event: UIEvent) {
          self.state = .failed
      }
      override func touchesEnded(_ touches: Set&lt;UITouch&gt;, with event: UIEvent) {
          self.state = .failed
      }
  }
  </code></pre>
  <p>This almost works, however, the problem this leaves me with is that since Rectangle() and TapView() are in a ZStack depending on where I place them in code I get <em>either</em> the touchDown location <em>or</em> the onLongPressGesture but not both.</p>
  <p>Other SO questions I've looked at but ran into similar problems are linked below</p>
  <p><a href="https://stackoverflow.com/questions/56513942/how-to-detect-a-tap-gesture-location-in-swiftui">How to detect a tap gesture location in SwiftUI?</a></p>
  <p><a href="https://stackoverflow.com/questions/28058082/swift-long-press-gesture-recognizer-detect-taps-and-long-press">Swift: Long Press Gesture Recognizer - Detect taps and Long Press</a>
  This one might be what I'm looking for but I'm not sure how to adapt it to SwiftUI.</p>