Is it possible to detect right-click in SwiftUI?

Original question here: https://stackoverflow.com/q/59280263/3939277



I'm writing a simple Mines app to help me get to know SwiftUI. As such, I want primary click (usually LMB) to "dig" (reveal whether there's a mine there), and secondary click (usually RMB or 2-finger click) to place a flag.



I have the digging working! But I can't figure out how to place a flag, because I can't figure out how to detect a secondary click.



Here's what I'm trying:



BoardSquareView(
    style: self.style(for: square),
    model: square
)
.gesture(TapGesture().modifiers(.control).onEnded(self.handleUserDidAltTap(square)))
.gesture(TapGesture().onEnded(self.handleUserDidTap(square)))



As I implied earlier, the function returned by `handleUserDidTap` is called properly on click, but the one returned by `handleUserDidAltTap` is only called when I hold down the Control key. That makes sense because that's what the code says... but I don't see any API which could make it register secondary clicks, so I don't know what else to do.



I also tried this, but the behavior seemed identical:



BoardSquareView(
    style: self.style(for: square),
    model: square
)
.gesture(TapGesture().modifiers(.control).onEnded(self.handleUserDidAltTap(square)))
.onTapGesture(self.handleUserDidTap(square))
Post not yet marked as solved Up vote post of BenLeggiero_0 Down vote post of BenLeggiero_0
3.4k views

Replies

You asked the question in SO:

https://stackoverflow.com/questions/59280263/how-can-i-detect-a-right-click-in-swiftui


You got an answer and accepted as correct solution.

That said, I did figure out a way to make this work. What you have to do is fall back on the older technology, and embed it into your SwiftUI view.


struct RightClickableSwiftUIView: NSViewRepresentable {
    func updateNSView(_ nsView: RightClickableView, context: NSViewRepresentableContext) {
        print("Update")
    }

    func makeNSView(context: Context) -> RightClickableView {
        RightClickableView()
    }
}

class RightClickableView : NSView {
    override func mouseDown(with theEvent: NSEvent) {
        print("left mouse")
    }

    override func rightMouseDown(with theEvent: NSEvent) {
        print("right mouse")
    }
}


Doesn't the proposed solution work for you ?

Why ask again here ? At least you should have referenced this SO thread.


As right click is not supported in SwiftUI, have you considered using tap and longPress instead of left and right click ?

  • That doesn't work for me because I asked about SwiftUI, not AppKit

Add a Comment
This thread is old... but I've posted a related question: how to pass and return a parameter to the NSView (i.e., right click triggers a SwiftUI popover). My passed binding does not update.

https://developer.apple.com/forums/thread/655056

attach this to your view. works in macos

.contextMenu {
    Button("Remove") {
        print("remove this view")
    }
}
  • Worked for me! Thanks!

Add a Comment