SwiftUI 地图显示注解
Posted
技术标签:
【中文标题】SwiftUI 地图显示注解【英文标题】:SwiftUI Map Display Annotations 【发布时间】:2020-06-23 20:15:08 【问题描述】:我决定从将 MKMapView 包装成 UIViewRepresentable 切换到 SwiftUI 中的新 Map()
。
我能够在Map()
中正确显示MKMapRect
,但我无法在那里显示两个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)
【问题讨论】:
【参考方案1】:您不再需要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)
)
【讨论】:
路由呢?是否可以在 SwiftUI 中实现? 我不知道。希望他们发布有关新地图功能的视频,但我想我们还没有得到。我们将看看它是否会在接下来的几个测试版中得到充实...... 你能用 MapAnnotation 做一个例子吗?我还需要显示一些文本,这就是我需要 MapAnnotation 的原因【参考方案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)
【讨论】:
【参考方案3】:应该如下所示(由于提供的快照中缺少依赖关系,未测试)
Map(mapRect: .constant(mapRect), annotationItems: coll) point in
MapAnnotation(coordinate: point.coordinate)
Text(point.title ?? "")
【讨论】:
代码编译正常,但我看不到红色注释,知道我在这里做错了什么吗? 我还用硬编码坐标更新了我的问题以进行测试。【参考方案4】:对于任何搜索 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
【讨论】:
以上是关于SwiftUI 地图显示注解的主要内容,如果未能解决你的问题,请参考以下文章