SwiftUI MapKit 使用协调器 - 如何访问地图 "view" 以调整 "didUpdateLocations" 中的可见区域?
SwiftUI MapKit use of coordinator - how to access map "view" to adjust visible area in "didUpdateLocations"?
我正在使用 SwiftUI MapKit 和协调器方法来获得更多功能。我不确定如何从“didUpdateLocations”委托方法回调更改地图显示的可见区域?不确定如何访问地图视图本身,因此我可以尝试“view.setVisibleMapRect”?
import SwiftUI
import MapKit
import CoreLocation
struct GCMapView {
var flight : Flight
func createAnnotations(flight : Flight) -> [MKAnnotation] {
// comment out for this post
return annotations
}
func makeCoordinator() -> Coordinator {
// print("makeCoordinator call - coordinates = ", coordinates.count)
return Coordinator(self)
}
class Coordinator: NSObject, MKMapViewDelegate, CLLocationManagerDelegate {
var parent: GCMapView
var locMgr = CLLocationManager()
init(_ parent: GCMapView) {
self.parent = parent
super.init()
locMgr.delegate = self
locMgr.desiredAccuracy = kCLLocationAccuracyBest
locMgr.activityType = .otherNavigation
locMgr.requestWhenInUseAuthorization()
locMgr.startUpdatingLocation()
}
// ------------------------------------
// CLLocationManagerDelegate Functions
// ------------------------------------
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let lastLoc = locations.last else { return }
let userCoord : CLLocationCoordinate2D = lastLoc.coordinate
print("didUpdateLocations - ", userCoord)
// ?? HOW TO PERFORM A SETVISIBLEMAPREC CALL FROM HERE????
}
// ------------------------------------
// MKMapViewDelegate Functions
// ------------------------------------
func mapView( _ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolylineRenderer(overlay: overlay)
renderer.strokeColor = .blue
renderer.lineWidth = 1.0
// renderer.alpha = 1.0
return renderer
}
}
}
extension GCMapView : UIViewRepresentable {
func makeUIView(context: Context) -> MKMapView {
let map = MKMapView()
map.delegate = context.coordinator
map.showsUserLocation = true
return map
}
func updateUIView(_ view: MKMapView, context: Context) {
let annotations = self.createAnnotations(flight: self.flight)
guard let lastAnnotation = annotations.last else {
return
}
// Add Annotations
view.addAnnotation(lastAnnotation)
// Add Overlays
view.removeOverlays(view.overlays)
let coords = flight.getCoordinates()
let polyline = MKPolyline(coordinates: coords, count: coords.count)
view.addOverlay(polyline)
// Zoom
let mapRect = GCMapHelper.MapRectFromCoords(coords: coords)
view.setVisibleMapRect(mapRect, edgePadding: UIEdgeInsets(top: 100, left: 100, bottom: 100, right: 100), animated: true)
}
}
您在错误的位置创建了 mapView 变量。您已在 makeUIView(context: Context)
函数中创建它,因此无法在其他任何地方访问它。而是将其声明为结构的参数 GCMapView
。然后,您可以根据需要在 locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
中将其引用为 parent.mapView
。所以在你的结构中:
struct GCMapView {
var flight : Flight
let map = MKMapView()
...
}
然后删除
中的声明
func makeUIView(context: Context) -> MKMapView {
//let map = MKMapView() // Remove this
map.delegate = context.coordinator
map.showsUserLocation = true
return map
}
最后:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let lastLoc = locations.last else { return }
let userCoord : CLLocationCoordinate2D = lastLoc.coordinate
print("didUpdateLocations - ", userCoord)
// ?? HOW TO PERFORM A SETVISIBLEMAPREC CALL FROM HERE????
parent.map.setVisibleMapRect(mapRect, edgePadding: padding, animated: true)
}
我正在使用 SwiftUI MapKit 和协调器方法来获得更多功能。我不确定如何从“didUpdateLocations”委托方法回调更改地图显示的可见区域?不确定如何访问地图视图本身,因此我可以尝试“view.setVisibleMapRect”?
import SwiftUI
import MapKit
import CoreLocation
struct GCMapView {
var flight : Flight
func createAnnotations(flight : Flight) -> [MKAnnotation] {
// comment out for this post
return annotations
}
func makeCoordinator() -> Coordinator {
// print("makeCoordinator call - coordinates = ", coordinates.count)
return Coordinator(self)
}
class Coordinator: NSObject, MKMapViewDelegate, CLLocationManagerDelegate {
var parent: GCMapView
var locMgr = CLLocationManager()
init(_ parent: GCMapView) {
self.parent = parent
super.init()
locMgr.delegate = self
locMgr.desiredAccuracy = kCLLocationAccuracyBest
locMgr.activityType = .otherNavigation
locMgr.requestWhenInUseAuthorization()
locMgr.startUpdatingLocation()
}
// ------------------------------------
// CLLocationManagerDelegate Functions
// ------------------------------------
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let lastLoc = locations.last else { return }
let userCoord : CLLocationCoordinate2D = lastLoc.coordinate
print("didUpdateLocations - ", userCoord)
// ?? HOW TO PERFORM A SETVISIBLEMAPREC CALL FROM HERE????
}
// ------------------------------------
// MKMapViewDelegate Functions
// ------------------------------------
func mapView( _ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolylineRenderer(overlay: overlay)
renderer.strokeColor = .blue
renderer.lineWidth = 1.0
// renderer.alpha = 1.0
return renderer
}
}
}
extension GCMapView : UIViewRepresentable {
func makeUIView(context: Context) -> MKMapView {
let map = MKMapView()
map.delegate = context.coordinator
map.showsUserLocation = true
return map
}
func updateUIView(_ view: MKMapView, context: Context) {
let annotations = self.createAnnotations(flight: self.flight)
guard let lastAnnotation = annotations.last else {
return
}
// Add Annotations
view.addAnnotation(lastAnnotation)
// Add Overlays
view.removeOverlays(view.overlays)
let coords = flight.getCoordinates()
let polyline = MKPolyline(coordinates: coords, count: coords.count)
view.addOverlay(polyline)
// Zoom
let mapRect = GCMapHelper.MapRectFromCoords(coords: coords)
view.setVisibleMapRect(mapRect, edgePadding: UIEdgeInsets(top: 100, left: 100, bottom: 100, right: 100), animated: true)
}
}
您在错误的位置创建了 mapView 变量。您已在 makeUIView(context: Context)
函数中创建它,因此无法在其他任何地方访问它。而是将其声明为结构的参数 GCMapView
。然后,您可以根据需要在 locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
中将其引用为 parent.mapView
。所以在你的结构中:
struct GCMapView {
var flight : Flight
let map = MKMapView()
...
}
然后删除
中的声明func makeUIView(context: Context) -> MKMapView {
//let map = MKMapView() // Remove this
map.delegate = context.coordinator
map.showsUserLocation = true
return map
}
最后:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let lastLoc = locations.last else { return }
let userCoord : CLLocationCoordinate2D = lastLoc.coordinate
print("didUpdateLocations - ", userCoord)
// ?? HOW TO PERFORM A SETVISIBLEMAPREC CALL FROM HERE????
parent.map.setVisibleMapRect(mapRect, edgePadding: padding, animated: true)
}