SwiftUI: Path's coordinateSpace SwiftUI: Path's coordinateSpace swift swift

SwiftUI: Path's coordinateSpace


Coordinate spaces come in three flavours: .local, .global and .named. The first two are obvious. The third, named coordinate spaces, are extremely useful in cases like yours. They are also useful in combination with GeometryReader. For more details on that, check https://swiftui-lab.com/geometryreader-to-the-rescue/

Named coordinate spaces let you express a coordinate of one view, in the coordinate space of another. For that, SwiftUI let you specify a name for a view's coordinate space. Then, in other places of your code, you can make a reference of it. In your example, naming the coordinate of your ZStack is the way to go.

Here's the refactored code:

Note: I moved the Path below, only so that it draws in front of the circles. And also, pay attention to the first Path, which is only there to prevent what I think is a bug in ZStack.

enter image description here

import SwiftUIstruct ContentView : View {    @State private var draggingLocation = CGPoint.zero    @State private var startLocation = CGPoint.zero    @State private var dragging = false    var body: some View {        let GR = DragGesture(minimumDistance: 10, coordinateSpace: .named("myCoordinateSpace"))            .onEnded { value in                self.dragging = false                self.draggingLocation = CGPoint.zero                self.startLocation = CGPoint.zero        }        .onChanged { value in            if !self.dragging {                self.dragging = true            }            if self.startLocation == CGPoint.zero {                self.startLocation = value.startLocation            }            self.draggingLocation = value.location        }        return ZStack(alignment: .topLeading) {            Circle()                .fill(self.dragging ? Color.blue : Color.red)                .frame(width: 100, height: 100)                .overlay(Text("Circle 1"))                .gesture(GR)                .offset(x: 75, y: 75)            Circle()                .fill(self.dragging ? Color.blue : Color.red)                .frame(width: 100, height: 100)                .overlay(Text("Circle 2"))                .gesture(GR)                .offset(x: 200, y: 200)            if self.dragging {                Path { path in                    path.move(to: CGPoint(x: self.startLocation.x-5, y: self.startLocation.y-5))                    path.addLine(to: CGPoint(x: self.draggingLocation.x-5, y: self.draggingLocation.y+5))                    path.addLine(to: CGPoint(x: self.draggingLocation.x+5, y: self.draggingLocation.y-5))                    path.addLine(to: CGPoint(x: self.startLocation.x+5, y: self.startLocation.y+5))                }                .fill(Color.black)            }        }        .coordinateSpace(name: "myCoordinateSpace")        .frame(width: 400, height: 400, alignment: .topLeading)        .background(Color.gray)    }}