SwiftUI MapKit 拖动注释

问题描述 投票:0回答:1

有人有经验或知道如何使用今年发布的新 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))
        }
    }
}
swiftui annotations mapkit drag
1个回答
0
投票

您可以使用

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
                }
            }
            
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.