我制作并实现了CLLocationManager和MKMapView,和地图差不多,希望对你有帮助:
简答:声明@Binding var foo: Any,您将能够在每次 foo 更改时在 GoogleMapView 中进行更改,在这种情况下 foo 是您的位置,因此您可以在每次 foo 时调用 animate更新了。
长答案:
首先我创建了一个符合 UIViewRepresentable 协议的 Mapview,就像你做的那样,但是添加了一个 @Binding 变量,这是我的“触发器”。
地图视图:
struct MapView: UIViewRepresentable {
@Binding var location: CLLocation // Create a @Binding variable that keeps the location where I want to place the view, every time it changes updateUIView will be called
private let zoomMeters = 400
func makeUIView(context: UIViewRepresentableContext<MapView>) -> MKMapView {
let mapView = MKMapView(frame: UIScreen.main.bounds)
return mapView
}
func updateUIView(_ mapView: MKMapView, context: Context) {
//When location changes, updateUIView is called, so here I move the map:
let region = MKCoordinateRegion(center: location.coordinate,
latitudinalMeters: CLLocationDistance(exactly: zoomMeters)!,
longitudinalMeters: CLLocationDistance(exactly: zoomMeters)!)
mapView.setRegion(mapView.regionThatFits(region), animated: true)
}
}
然后我将我的 MapView 放在我的 ContentView 中,传递一个 location 参数,我将在下面解释:
内容视图:
struct ContentView: View {
@ObservedObject var viewModel: ContentViewModel
var body: some View {
VStack {
MapView(location: self.$viewModel.location)
}
}
}
在我的 ViewModel 中,我使用委托处理位置更改,下面是 cmets 中包含更多详细信息的代码:
class ContentViewModel: ObservableObject {
//location is a Published value, so the view is updated every time location changes
@Published var location: CLLocation = CLLocation.init()
//LocationWorker will take care of CLLocationManager...
let locationWorker: LocationWorker = LocationWorker()
init() {
locationWorker.delegate = self
}
}
extension ContentViewModel: LocationWorkerDelegate {
func locationChanged(lastLocation: CLLocation?) {
//Location changed, I change the value of self.location, it is a @Published value so it will refresh the @Binding variable inside MapView and call MapView.updateUIView
self.location = CLLocation.init(latitude: lastLocation!.coordinate.latitude, longitude: lastLocation!.coordinate.latitude)
}
}
最后是处理 CLLocationManager() 的 LocationWorker:
class LocationWorker: NSObject, ObservableObject {
private let locationManager = CLLocationManager()
var delegate: LocationWorkerDelegate?
let objectWillChange = PassthroughSubject<Void, Never>()
@Published var locationStatus: CLAuthorizationStatus? {
willSet {
objectWillChange.send()
}
}
@Published var lastLocation: CLLocation? {
willSet {
objectWillChange.send()
}
}
override init() {
super.init()
self.locationManager.delegate = self
//...
}
}
protocol LocationWorkerDelegate {
func locationChanged(lastLocation: CLLocation?)
}
extension LocationWorker: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last else { return }
self.lastLocation = location
//When location changes: I use my delegate ->
if delegate != nil {
delegate!.locationChanged(lastLocation: lastLocation)
}
}
}