Я работаю над приложением macOS со SwiftUI, которое должно иметь возможность создавать, упорядочивать и удалять геометрические фигуры на экране. Создание и перетаскивание фигур уже работает довольно хорошо с помощью контекстного меню.
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, которые решают мою проблему?