在 macOS 应用程序中获取右键单击的位置
Posted
技术标签:
【中文标题】在 macOS 应用程序中获取右键单击的位置【英文标题】:getting position of right click in macos app 【发布时间】:2020-08-27 09:31:57 【问题描述】:我正在开发一个带有 SwiftUI 的 macOS 应用程序,它应该能够在屏幕上创建、排列和删除几何形状。使用上下文菜单已经可以很好地创建和拖动形状。
import SwiftUI
class Canvas: ObservableObject
@Published var nodes: [Node] = []
func addNode(position: CGPoint) -> Void
nodes.append(Node(id: UUID(), position: position))
struct CanvasView: View
@ObservedObject var canvas = Canvas()
var body: some View
ZStack
Color(red: 0.9, green: 0.9, blue: 0.8)
.contextMenu
Button( action:
self.canvas.addNode(position: CGPoint(x: 400, y: 400))
)
Text("Add Node ...")
ForEach(canvas.nodes) node in
NodeView(node: node)
class Node: Identifiable, ObservableObject
@Published var id: UUID
@Published var position: CGPoint
@Published var positionProxy: CGPoint
init (id: UUID, position: CGPoint)
self.id = id
self.position = position
self.positionProxy = position
struct NodeView: View
@ObservedObject var node: Node
init(node: Node)
self.node = node
var draggingNode: some Gesture
DragGesture(coordinateSpace: .global)
.onChanged value in
self.node.position.x = value.translation.width + self.node.positionProxy.x;
self.node.position.y = -value.translation.height + self.node.positionProxy.y
.onEnded value in
self.node.position.x = value.translation.width + self.node.positionProxy.x;
self.node.position.y = -value.translation.height + self.node.positionProxy.y;
self.node.positionProxy = self.node.position
var body: some View
RoundedRectangle(cornerRadius: 20)
.fill(Color.white)
.frame(width: 100, height: 100)
.overlay(
RoundedRectangle(cornerRadius: 20)
.stroke(lineWidth: 1)
.fill(Color.gray)
)
.position(node.position)
.gesture(draggingNode)
我的问题是所有创建的形状都出现在相同的预定义位置
position: CGPoint(x: 400, y: 400)
在屏幕上,我必须手动将它们中的每一个移动到其预期位置。我正在寻找一种方法来跟踪右键单击期间的光标位置或上下文菜单位置以将其用作节点位置并能够编写类似
self.canvas.addNode(position: cursorPosition)
而不是
self.canvas.addNode(position: CGPoint(x: 400, y: 400))
Swift 中是否有任何功能可以解决我的问题,最好是在 SwiftUI 中?
【问题讨论】:
【参考方案1】:目前无法在 SwiftUI 中检测鼠标点击位置。解决您的问题的方法可能是使用 SwiftUI Gesture
的组合。
以下代码可用于检测(简单或双击)左键单击位置:
import SwiftUI
struct ClickGesture: Gesture
let count: Int
let coordinateSpace: CoordinateSpace
typealias Value = SimultaneousGesture<TapGesture, DragGesture>.Value
init(count: Int = 1, coordinateSpace: CoordinateSpace = .local)
precondition(count > 0, "Count must be greater than or equal to 1.")
self.count = count
self.coordinateSpace = coordinateSpace
var body: SimultaneousGesture<TapGesture, DragGesture>
TapGesture(count: count)
.simultaneously(with: DragGesture(minimumDistance: 0, coordinateSpace: coordinateSpace))
func onEnded(perform action: @escaping (CGPoint) -> Void) -> some Gesture
ClickGesture(count: count, coordinateSpace: coordinateSpace)
.onEnded (value: Value) -> Void in
guard value.first != nil else return
guard let startLocation = value.second?.startLocation else return
guard let endLocation = value.second?.location else return
guard ((startLocation.x-1)...(startLocation.x+1)).contains(endLocation.x),
((startLocation.y-1)...(startLocation.y+1)).contains(endLocation.y) else return
action(startLocation)
extension View
func onClickGesture(
count: Int,
coordinateSpace: CoordinateSpace = .local,
perform action: @escaping (CGPoint) -> Void
) -> some View
gesture(ClickGesture(count: count, coordinateSpace: coordinateSpace)
.onEnded(perform: action)
)
func onClickGesture(
count: Int,
perform action: @escaping (CGPoint) -> Void
) -> some View
onClickGesture(count: count, coordinateSpace: .local, perform: action)
func onClickGesture(
perform action: @escaping (CGPoint) -> Void
) -> some View
onClickGesture(count: 1, coordinateSpace: .local, perform: action)
您可以以与onTapGesture()
或TapGesture
非常相似的方式使用它:
struct MyView: View
var body: some View
Rectangle()
.frame(width: 600, height: 400)
.onClickGesture(count: 2) location in
print("Double tap at location \(location)")
您可以另外指定一个 CoordinateSpace。
【讨论】:
以上是关于在 macOS 应用程序中获取右键单击的位置的主要内容,如果未能解决你的问题,请参考以下文章
在 SwiftUI for macOS 应用程序中获取点击手势的鼠标/指针位置
C#中dataGridView怎么实现右键单击时获取点击位置所在的行数RowIndex?