SwiftUI/MapKit注释选择和导航 [英] SwiftUI / MapKit Annotation Selection and Navigation
问题描述
我目前有一个SwiftUI视图,该视图显示一个充满针脚的地图.该地图有一个委托,可以确定何时选择了引脚,并获取与该引脚关联的自定义对象.
I currently have a SwiftUI view that displays a map full of pins. The map has a delegate which can determine when a pin is selected and get the custom object associated with that pin.
问题在于,一旦委托人确定选择了引脚,我就需要我的SwiftUI视图使用委托人检索到的自定义对象导航/推送到详细信息页面.
The problem is that once the delegate determines that the pin has been selected, I need my SwiftUI view to navigate/push to a detail page with the custom object that the delegate retrieved.
我能想到的最好的比较是尝试将选定的注释视为主视图的导航链接按钮.
The best comparison I can think of is trying to treat the selected annotation as a navigation link button for the main view.
如何从地图委托人传递到SwiftUI视图?
How do I communicate from the map delegate to the SwiftUI view?
import SwiftUI
import MapKit
/// The SwiftUI view I am referring to
struct ContentView: View {
var body: some View {
ZStack {
MapView()
}
.edgesIgnoringSafeArea(.all)
}
}
/// The custom object I am referring to
class LandmarkAnnotation: NSObject, MKAnnotation {
let title: String?
let subtitle: String?
let coordinate: CLLocationCoordinate2D
init(title: String?,
subtitle: String?,
coordinate: CLLocationCoordinate2D) {
self.title = title
self.subtitle = subtitle
self.coordinate = coordinate
}
}
/// The delegate I am referring to
class MapViewCoordinator: NSObject, MKMapViewDelegate {
var mapViewController: MapView
init(_ control: MapView) {
self.mapViewController = control
}
func mapView(_ mapView: MKMapView, viewFor
annotation: MKAnnotation) -> MKAnnotationView?{
...
return annotationView
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let circle = MKCircleRenderer(overlay: overlay)
...
return circle
}
/// This is where the delegate gets the object for the selected annotation
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
if let v = view.annotation as? LandmarkAnnotation {
print(v.coordinate)
}
}
}
struct MapView: UIViewRepresentable {
var markers: [CLLocationCoordinate2D] = [CLLocationCoordinate2D(
latitude: 34.055404, longitude: -118.249278),CLLocationCoordinate2D(
latitude: 34.054097, longitude: -118.249664), CLLocationCoordinate2D(latitude: 34.053786, longitude: -118.247636)]
var convertedMarkers: [LandmarkAnnotation] = []
init() {
convertedMarkers = cordToMark(locations: self.markers)
}
func makeUIView(context: Context) -> MKMapView{
MKMapView(frame: .zero)
}
func cordToMark(locations: [CLLocationCoordinate2D]) -> [LandmarkAnnotation] {
var marks: [LandmarkAnnotation] = []
for cord in locations {
let mark = LandmarkAnnotation(title: "Test", subtitle: "Sub", coordinate: cord)
marks.append(mark)
}
return marks
}
func makeCoordinator() -> MapViewCoordinator{
MapViewCoordinator(self)
}
func updateUIView(_ view: MKMapView, context: Context){
let coordinate = CLLocationCoordinate2D(
latitude: 34.0537767, longitude: -118.248)
let mapCamera = MKMapCamera()
mapCamera.centerCoordinate = coordinate
mapCamera.pitch = 10
mapCamera.altitude = 3000
view.camera = mapCamera
view.mapType = .mutedStandard
view.delegate = context.coordinator
view.addAnnotations(self.convertedMarkers)
let radiusCircle = MKCircle(center: CLLocationCoordinate2D(
latitude: 34.0537767, longitude: -118.248), radius: 300 as CLLocationDistance)
view.addOverlay(radiusCircle)
let locationCircle = MKCircle(center: CLLocationCoordinate2D(
latitude: 34.0537767, longitude: -118.248), radius: 3 as CLLocationDistance)
view.addOverlay(locationCircle)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.environment(\.colorScheme, .light)
}
}
这是模拟器中显示的地图图像
Here is an image of the map that is displayed in the simulator
推荐答案
这里是个主意(草稿)
- 向可表示形式添加回调
struct MapView: UIViewRepresentable {
var didSelect: (LandmarkAnnotation) -> () // callback
- 在
ContentView
中
ZStack {
MapView() { annotation in
// store/pass annotation somewhere, and
// activate navigation link here, eg. via isActive or selection
}
}
- 激活委托中的回调
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
if let v = view.annotation as? LandmarkAnnotation {
print(v.coordinate)
self.mapViewController.didSelect(v) // << here !!
}
}
这篇关于SwiftUI/MapKit注释选择和导航的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!