I trying to add the location of schedule as mapmarks on map of MapKit, and connect them order by time.
But the Path didn't show up, and I sure that the start
and end
are at the right position. So I wonder is the Path not allowed to overight the MapView? If so. How do I implement this?
ZStack{
Map(coordinateRegion: $region, annotationItems: markList) { location in
MapMarker(coordinate: CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude), tint: .red)
}
.frame(height: proxyHight * 0.35)
.padding([.leading, .trailing], 22)
.cornerRadius(20)
.shadow( radius: 3, x: 3, y: 3)
Path { path in
// Draw dotted lines between markers
for (index, location) in markList.enumerated() {
if index < markList.count - 1 {
let nextLocation = markList[index + 1].coordinate
let start = CGPoint(x: location.coordinate.longitude, y: location.coordinate.latitude)
let end = CGPoint(x: nextLocation.longitude, y: nextLocation.latitude)
//print("Drawing line from \(start) to \(end)")
path.move(to: start)
path.addLine(to: end)
}
}
}
.stroke(style: StrokeStyle(lineWidth: 2, dash: [5]))
.foregroundColor(Color.blue)
}
The CGPoint
s you pass to Path
represents points in view space, not coordinates on earth. (0, 0) would be the point on the top left of the screen, not somewhere in the ocean near Africa.
Before iOS 17, SwiftUI's Map
had very limited functionality, and this was very difficult to draw lines accurately on the map. I would suggest wrapping a MKMapView
with a UIViewRepresentable
. This gist shows a simple example.
In iOS 17+, you should use MapPolyline
, which draws a path on the map.
Assuming markList.map(\.coordinate)
is a [CLLocationCoordinate2D]
, you can write:
Map(initialPosition: .region(region)) {
ForEach(markList) { mark in
Marker("", coordinate: mark.coordinate)
}
MapPolyline(coordinates: markList.map(\.coordinate))
.stroke(.blue, style: StrokeStyle(lineWidth: 2, dash: [5]))
}
Note that if you need to track the map region, you should use onMapCameraChange
:
.onMapCameraChange(frequency: .continuous) {
// do something with $0.region
}