有人有经验或知道如何使用今年发布的新 MapKit 功能拖放注释和标记吗?
import MapKit
import SwiftUI
struct SwiftUIView: View {
@State private var position: MapCameraPosition = .automatic
var body: some View {
Map(position: $position) {
Marker("name", coordinate: CLLocationCoordinate2D(latitude: 48.186915, longitude: 11.164182))
}
}
}
您可以使用
MapReader
和 dropDestination
尝试这种方法,以允许从 pins
列表中拖动并将它们放到地图上。
例如,使用鼠标/手指在地图上拖动(长按)
pin-1
。
进入地图后,您可以在地图周围拖动 pin
。
按
Drag on/off
按钮可拖动 pin
或地图功能。
单击/点击特定的
pin
将其选中,然后使用 Drag on
在地图上拖动。
这里是使用 SwiftUI MapKit 拖放注释的完整工作示例代码。
import Foundation
import SwiftUI
import MapKit
import CoreLocation
struct PinPoint: Identifiable {
let id = UUID()
var name: String
var coord: CLLocationCoordinate2D
init(coord: CLLocationCoordinate2D, name: String) {
self.coord = coord
self.name = name
}
}
struct ContentView: View {
@State var isDraging = false
@State var modes = MapInteractionModes.all
@State var dragId = UUID()
@State var pinList = [PinPoint]()
@State private var cameraPosition: MapCameraPosition = .camera(MapCamera(centerCoordinate: CLLocationCoordinate2D(latitude: 35.68, longitude: 139.75), distance: 4000.0, heading: 0, pitch: 0))
var body: some View {
VStack {
HStack {
// just a button to turn on/off map dragging
Button(action: { isDraging.toggle() }) {
VStack {
Image(systemName: "move.3d")
.resizable()
.frame(width: 25, height: 25)
.foregroundColor(isDraging ? .red : .blue)
Text(isDraging ? "Drag on" : "Drag off")
.font(.caption)
.foregroundColor(isDraging ? .red : .blue)
}.frame(width: 80, height: 60)
}.buttonStyle(.bordered)
Spacer()
// list of pins to drop on the map
ForEach(["pin-1", "pin-2", "pin-3"], id: \.self) { pin in
Text(pin)
.border(.red)
.draggable(pin)
}
}
MapReader { reader in
Map(position: $cameraPosition, interactionModes: modes) {
ForEach(pinList) { pin in
Annotation(pin.name, coordinate: pin.coord) {
Image(systemName: "mappin.circle")
.resizable()
.foregroundStyle(dragId == pin.id ? .red : .green)
.frame(width: 30, height: 30)
// tap on the pin to select it before dragging on map
.onTapGesture {
dragId = pin.id
}
}
}
}.edgesIgnoringSafeArea(.all)
// drag the pin on the map
.gesture(DragGesture()
.onChanged { drag in
if isDraging, let ndx = pinList.firstIndex(where: {$0.id == dragId}),
let location = reader.convert(drag.location, from: .local) {
pinList[ndx].coord = location
}
}
)
// change the map mode so we can drag the pin or the map
.onChange(of: isDraging) {
if isDraging {
modes.subtract(.all)
} else {
dragId = UUID()
modes.update(with: .all)
}
}
// receive the pin drop
.dropDestination(for: String.self) { items, location in
if let pin = items.first,
let coord = reader.convert(location, from: .local) {
let pinPoint = PinPoint(coord: coord, name: pin)
pinList.append(pinPoint)
dragId = pinPoint.id
isDraging = true
}
return true
}
}
}
}
}