如何从UIRepresentable MapView访问底层GMSMapView



在我的应用程序中,我有一个ViewModel(MapViewModel(类、一个UIRepresentable类和ContentView。我正在寻找一种方法来访问ViewModel中的GMSMapView视图,该视图是作为UIRepresentable类创建的。

ContentView.swift:

import SwiftUI
import Combine
struct ContentView: View {
@State private var selection = 0
@State private var dragOffset = CGSize.zero
@ObservedObject var mapViewModel : MapViewModel = MapViewModel()
var body: some View {
GeometryReader { geo in
TabView(selection: self.$selection) {
MapView()
.edgesIgnoringSafeArea(.all)
.tabItem {
VStack {
Image(systemName: "house")
Text("Home")
}
}
.tag(0)
Text("Second Page")
.tabItem {
VStack {
Image(systemName: "gear")
Text("Settings")
}
}
.tag(1)
Text("Third Page")
.tabItem {
VStack {
Image(systemName: "gear")
Text("Third Page")
}
}
.tag(2)
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}

MapViewModel.swift:

import Foundation
import Combine
import GoogleMaps
import os
class MapViewModel: NSObject, ObservableObject {
let lm = CLLocationManager()
var myLocations =  [CLLocation]()

override init() {
super.init()
lm.delegate = self
lm.desiredAccuracy = kCLLocationAccuracyBest
lm.requestWhenInUseAuthorization()
lm.pausesLocationUpdatesAutomatically = false
lm.allowsBackgroundLocationUpdates = true
lm.startUpdatingLocation()
}
}
extension MapViewModel: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
//self.status = status
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
os_log("locationManager:didUpdateLocations: received location",log: Log.general, type: .debug)
}
}

MapView.swift:

import UIKit
import SwiftUI
import GoogleMaps
struct MapView: UIViewRepresentable {
func makeUIView(context: Context) -> GMSMapView {
let camera = GMSCameraPosition.camera(withLatitude: 30.267153, longitude: -97.7430608, zoom: 6.0)
let gmsMapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
gmsMapView.delegate = context.coordinator
return gmsMapView
}
func updateUIView(_ mapView: GMSMapView, context: Self.Context) {
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, GMSMapViewDelegate {
var parent: MapView
init(_ parent: MapView) {
self.parent = parent
}       
}
}
struct GoogleMapView_Previews: PreviewProvider {
static var previews: some View {
MapView()
}
}

关于如何在MapViewModel中访问gmsMapView对象的任何想法。我需要在地图上划线。。。谢谢

我通过将折线过度值定义为@Published并通过updateUI中的viewmodel访问它,从而解决了这个问题。因此,我没有尝试从视图模型访问地图视图,而是让视图添加多段线覆盖。希望这能帮助其他人。感谢

ContentView.swift:

struct ContentView: View {
@State private var selection = 0
@State private var dragOffset = CGSize.zero
@ObservedObject var mapViewModel: MapViewModel
var body: some View {
GeometryReader { geo in
TabView(selection: self.$selection) {
MapView()
.edgesIgnoringSafeArea(.all)
.tabItem {
VStack {
Image(systemName: "house")
Text("Home")
}
}
.tag(0)
Text("Second Page")
.tabItem {
VStack {
Image(systemName: "gear")
Text("Settings")
}
}
.tag(1)
Text("Third Page")
.tabItem {
VStack {
Image(systemName: "gear")
Text("Third Page")
}
}
.tag(2)
}
}
}
}

MapView:

struct MapView: UIViewRepresentable {
@ObservedObject var mapViewModel = MapViewModel()
func makeUIView(context: Context) -> GMSMapView {
let camera = GMSCameraPosition.camera(withLatitude: 30.5986015, longitude: -97.8210401, zoom: 20.0)
let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
mapView.isMyLocationEnabled = true
mapView.animate(toViewingAngle: 45)
mapView.delegate = context.coordinator
return mapView
}
func updateUIView(_ mapView: GMSMapView, context: Self.Context) {
if (mapViewModel.polyline != nil) {
print("updateUIView: Polyline = (mapViewModel.polyline!.description)")
os_log("updateUIView: Polyline = %{Public}s",log: Log.general, type: .debug, mapViewModel.polyline!.description)
mapViewModel.polyline!.strokeColor = UIColor.red
mapViewModel.polyline!.strokeWidth = 5.0
mapViewModel.polyline!.map = mapView
}
if (mapViewModel.locChanged && mapViewModel.myLocations.count > 0) {
print("updateUIView: Refocus camera on last location")
os_log("updateUIView: Refocus camera on last location",log: Log.general, type: .debug, mapViewModel.polyline!.description)
let camera = GMSCameraPosition.camera(withLatitude: (mapViewModel.myLocations.last?.coordinate.latitude)!, longitude: (mapViewModel.myLocations.last?.coordinate.longitude)!, zoom: 20.0)
let _ = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
}
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, GMSMapViewDelegate {
var parent: MapView
init(_ parent: MapView) {
self.parent = parent
}
}
}

MapViewModel:

class MapViewModel: NSObject, ObservableObject {
.
.
.    
@Published var polyline: GMSPolyline?
@Published var locChanged: Bool = false
override init() {
super.init()
.
.
.       
polyline = nil
}
.
.
.        
func draw(myLocations: [CLLocation], color: UIColor) {
os_log("MapViewController: Drawing Track for last two Locations",log: Log.general, type: .info)
print("MapViewController: Drawing Track for last two Locations")
let path = GMSMutablePath()
let c1 = myLocations[myLocations.count - 1].coordinate
let c2 = myLocations[myLocations.count - 2].coordinate
path.add(c1)
path.add(c2)
polyline = GMSPolyline(path: path)
print("draw: Polyline = (polyline!.description)")
polyline!.strokeColor = color
polyline!.strokeWidth = 5.0
}
.
.
.   
extension MapViewModel: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
os_log("locationManager:didUpdateLocations: received location",log: Log.general, type: .debug)
guard let lastLocation: CLLocation = locations.last else {
os_log("locationManager:didUpdateLocations: received null location",log: Log.general, type: .debug)
return
}

if (myLocations.count >= 2) {
os_log("MapViewController: updateLocation: Calling draw method with count = %{Public}s",log: Log.general, type: .debug, myLocations.count.description)
self.draw(myLocations: self.myLocations, color:.red)
}
.
.
.    
} else {
os_log("LocationManager: Bad Location...",log: Log.general, type: .error)
badLocationCount += 1
locChanged = false
}
}
}

相关内容

  • 没有找到相关文章

最新更新