如何检测 SwiftUI 中的右键单击?

Sup*_*tar 16 right-click event-handling mouseevent swift swiftui

我正在编写一个简单的 Mines 应用程序来帮助我了解 SwiftUI。因此,我希望主要点击(通常是 LMB)来“挖掘”(显示那里是否有地雷),然后二次点击(通常是人民币)来放置一个标志。

我有挖掘工作!但我无法弄清楚如何放置标志,因为我无法弄清楚如何检测二次点击。

这是我正在尝试的

BoardSquareView(
    style: self.style(for: square),
    model: square
)
.gesture(TapGesture().modifiers(.control).onEnded(self.handleUserDidAltTap(square)))
.gesture(TapGesture().onEnded(self.handleUserDidTap(square)))
Run Code Online (Sandbox Code Playgroud)

正如我之前暗示的那样,返回的函数handleUserDidTap在单击时正确调用,但返回的handleUserDidAltTap函数仅在我按住 Control 键时调用。这是有道理的,因为这就是代码所说的……但我没有看到任何可以注册二次点击的 API,所以我不知道还能做什么。

我也试过这个,但行为似乎相同:

BoardSquareView(
    style: self.style(for: square),
    model: square
)
.gesture(TapGesture().modifiers(.control).onEnded(self.handleUserDidAltTap(square)))
.onTapGesture(self.handleUserDidTap(square))
Run Code Online (Sandbox Code Playgroud)

B.T*_*.T. 11

就目前 SwiftUI 的情况而言,这不是直接可能的。我相信它会在未来,但目前,TapGesture它显然主要集中在没有“右键单击”概念的 iOS 用例上,所以我认为这就是为什么这被忽略了。请注意,“长按”概念是以 的形式出现的一等公民LongPressGesture,并且几乎只用于支持该理论的 iOS 上下文中。

也就是说,我确实想出了一种方法来完成这项工作。您需要做的是退回旧技术,并将其嵌入到您的 SwiftUI 视图中。

struct RightClickableSwiftUIView: NSViewRepresentable {
    func updateNSView(_ nsView: RightClickableView, context: NSViewRepresentableContext<RightClickableSwiftUIView>) {
        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")
    }
}
Run Code Online (Sandbox Code Playgroud)

我对此进行了测试,它在一个相当复杂的 SwiftUI 应用程序中对我有用。这里的基本方法是:

  1. 将您的聆听组件创建为NSView.
  2. 用一个实现NSViewRepresentable.
  3. 将您的实现放入您想要的 UI 中,就像您对任何其他 SwiftUI 视图所做的一样。

不是一个理想的解决方案,但它现在可能已经足够了。我希望这可以解决您的问题,直到 Apple 进一步扩展 SwiftUI 的功能。

  • 韦尔普;看来这是今天最好的答案了。赏金是你的!希望有一天我们能有一个正式的解决方案。 (3认同)

Col*_*lay 6

这并不能精确地解决扫雷用例,而是contextMenu处理 SwiftUI macOS 应用程序中右键单击的一种方法。

例如:

.contextMenu {
    Button(action: {}, label: { Label("Menu title", systemImage: "icon") })
}
Run Code Online (Sandbox Code Playgroud)

将响应 macOS 上的右键单击和 iOS 上的长按