我决定从将MKMapView包装到UIViewRepresentable中切换到SwiftUI中的新Map()
。
我能够在MKMapRect
中正确显示Map()
,但是在此处无法显示两个MKPointAnnotation
。而且我在这些注释之间的路线没有显示
它要求我提供一个RandomAccessCollection
和一个(Identifiable) -> MapAnnotationProtocol>
,但我不知道该放在哪里。
任何想法我应该在(Identifiable) -> MapAnnotationProtocol
中输入什么?
import SwiftUI
import MapKit
extension MKPointAnnotation: Identifiable { }
struct ItemView: View {
@ObservedObject var itemViewModel: ItemViewModel
@State var coll = [MKPointAnnotation]()
func onAppear() {
let requestAnnotation = MKPointAnnotation()
requestAnnotation.coordinate = CLLocationCoordinate2D(latitude: 46.2004781, longitude: 6.1346497)
requestAnnotation.title = "Package"
let destinationAnnotation = MKPointAnnotation()
destinationAnnotation.coordinate = CLLocationCoordinate2D(latitude: 47.1420446, longitude: 9.5204032)
destinationAnnotation.title = "Destination"
coll.append(requestAnnotation)
coll.append(destinationAnnotation)
}
var body: some View {
VStack {
if let mapRect = itemViewModel.route?.polyline.boundingMapRect {
Map(mapRect: .constant(mapRect), annotationItems: coll) { point in
MapAnnotation(coordinate: point.coordinate) {
Text(point.title ?? "")
}
}
}
}
.onAppear(perform: self.onAppear)
}
}
答案 0 :(得分:3)
您不再需要执行MKPointAnnotation
。当前,在Xcode 12.0 Beta中,SwiftUI提供了三种结构来满足MapAnnotationProtocol
:
MapAnnotation
MapMarker
MapPin
RandomAccessCollection
应该是采用Identifiable
的对象的任何集合(将执行数组操作)。这些在Map
初始化程序的最终参数中用作块的参数。
Map(coordinateRegion: $container.region,
annotationItems: container.annotationLocations) {
(location) -> MapPin in
MapPin(coordinate: location.coordinate)
})
答案 1 :(得分:2)
在我看来MapAnnotation
要求您实现将在地图上呈现的整个视图,因此,如果您既想要红色图钉又需要一些文本,则必须自己创建该图钉(例如作为带有SF符号的图像的实例)。当然,它看起来不如MapMarker
的图钉,但至少是一个开始。
Map(coordinateRegion: .constant(mapRect), annotationItems: coll) { annotationItem in
MapAnnotation(coordinate: annotationItem.coordinate) {
VStack {
Group {
Image(systemName: "mappin.circle.fill")
.resizable()
.frame(width: 30.0, height: 30.0)
Circle()
.frame(width: 8.0, height: 8.0)
}
.foregroundColor(.red)
Text(annotationItem.title)
}
}
}
答案 2 :(得分:1)
应该类似于以下内容(由于提供的快照中缺少相关性,因此未经测试)
Map(mapRect: .constant(mapRect), annotationItems: coll) { point in
MapAnnotation(coordinate: point.coordinate) {
Text(point.title ?? "")
}
}
答案 3 :(得分:0)
对于任何搜索 SwiftUI MKPolyline 路线的人
struct MapView: View {
@ObservedObject var viewModel: MapViewModel
var body: some View {
VStack(spacing: 0) {
Text("Status")
.padding()
MapViewRepresentable(exampleRoute: viewModel.exampleRoute)
Button("Button", action: { })
.padding()
}
}
}
struct MapView_Previews: PreviewProvider {
static var previews: some View {
MapView(viewModel: MapViewModel())
}
}
struct MapViewRepresentable: UIViewRepresentable {
private let initialRegion = CoordinateRegion.initial
let exampleRoute: MKPolyline
func makeCoordinator() -> Coordinator {
return Coordinator(self)
}
func makeUIView(context: UIViewRepresentableContext<MapViewRepresentable>) -> MKMapView {
let mapView = MKMapView()
mapView.delegate = context.coordinator
mapView.setRegion(initialRegion, animated: false)
mapView.showsUserLocation = true
mapView.addOverlay(exampleRoute)
return mapView
}
func updateUIView(_ view: MKMapView,
context: UIViewRepresentableContext<MapViewRepresentable>) {
}
class Coordinator: NSObject, MKMapViewDelegate {
let parent: MapViewRepresentable
init(_ mapView: MapViewRepresentable) {
parent = mapView
}
func mapView(_ mapView: MKMapView,
rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let polylineRenderer: MKPolylineRenderer = MKPolylineRenderer(overlay: overlay)
polylineRenderer.lineWidth = 3
polylineRenderer.strokeColor = UIColor.red
return polylineRenderer
}
}
}
class MapViewModel: ObservableObject {
@Published private(set) var exampleRoute = createPolylines()
static func createPolylines() -> MKPolyline {
var coordinates1 = createExampleRoute()
return MKPolyline(coordinates: &coordinates1, count: coordinates1.count)
}
static func createExampleRoute() -> [CLLocationCoordinate2D] {
return [CLLocationCoordinate2D(latitude: 60.608905, longitude: 39.814428),
CLLocationCoordinate2D(latitude: 60.609073, longitude: 39.812000),
CLLocationCoordinate2D(latitude: 60.610429, longitude: 39.812071)]
}
}
struct CoordinateRegion {
static let initial = MKCoordinateRegion(center: CLLocationManager().location?.coordinate
?? CLLocationCoordinate2D(latitude: 60.608905,
longitude: 39.814428),
span: MKCoordinateSpan(latitudeDelta: 0.05,
longitudeDelta: 0.05))
func getCurrentLocation() -> CLLocationCoordinate2D {
return CLLocationManager().location!.coordinate
}
}