ios - 在我的代码中遇到 ObserveObject Array 更改的问题
问题描述
目前,我的代码在用户当前位置附近找到附近的公园,并在控制台中输出名称/位置(使用 Google Maps & Google Places API)。 控制台输出。 我试图在我的应用程序中完成的下一步是在返回 mapView 之前使用 GoogleMapsView.swift 文件中的标记对地图上的每个公园进行注释。我的问题是,在找到公园位置后,我无法弄清楚如何执行此操作。所以我的问题是如何观察阵列中的公园位置变化,以便之后能够在地图上标记它们?这是我的代码。在我的 ContentView.swift 中,我只是将 GoogleMapsView 传递到视图中。
PlacesManager.swift:
import GooglePlaces
class PlacesManager: NSObject, ObservableObject, LocationManagerDelegate {
@Published var places = [Place]()
lazy var googleClient: GoogleClientRequest = GoogleClient()
var locationManager: LocationManager?
var searchRadius : Int = 700
override init() {
super.init()
load()
}
func load() {
locationManager = LocationManager()
locationManager?.delegate = self
}
func locationDidChange(location: CLLocation) {
let lat = location.coordinate.latitude
let long = location.coordinate.longitude
let newLocation: CLLocation = CLLocation(latitude: lat, longitude: long)
fetchGoogleData(forLocation: newLocation, searchRadius: 700)
}
func fetchGoogleData(forLocation: CLLocation, searchRadius: Int) {
//guard let location = currentLocation else { return }
googleClient.getGooglePlacesData(location: forLocation, withinMeters: searchRadius) { (response) in
self.places = response.results
}
}
//... print parks in console code is here
}
LocationManager.swift:
protocol LocationManagerDelegate: class {
func locationDidChange(location: CLLocation)
}
class LocationManager: NSObject, ObservableObject {
weak var delegate: LocationManagerDelegate?
private let locationManager = CLLocationManager()
@Published var location: CLLocation? {
willSet { objectWillChange.send() }
}
var latitude: CLLocationDegrees {
return location?.coordinate.latitude ?? 0
}
var longitude: CLLocationDegrees {
return location?.coordinate.longitude ?? 0
}
override init() {
super.init()
let status = CLLocationManager.authorizationStatus()
if status == .notDetermined {
locationManager.requestWhenInUseAuthorization()
}
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
}
}
}
extension LocationManager: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager,didChangeAuthorization status: CLAuthorizationStatus) {
guard status == .authorizedWhenInUse else {
return
}
locationManager.requestLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.first else {
return
}
self.location = location
self.delegate?.locationDidChange(location: location)
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error)
}
}
GoogleMapsView.swift:
struct GoogleMapsView: UIViewRepresentable {
@ObservedObject var locationManager = LocationManager()
@ObservedObject var place: PlacesManager = PlacesManager()
func makeUIView(context: Self.Context) -> GMSMapView {
let camera = GMSCameraPosition.camera(withLatitude: locationManager.latitude, longitude: locationManager.longitude, zoom: 15)
let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
mapView.isMyLocationEnabled = true
mapView.settings.rotateGestures = false
mapView.settings.tiltGestures = false
mapView.isIndoorEnabled = false
mapView.isTrafficEnabled = false
mapView.isBuildingsEnabled = false
mapView.settings.myLocationButton = true
return mapView
}
}
解决方案
在我的项目中,我使用 UIKit 来处理地图和标记,该方法与您发布的方法完全不同。无论如何,这是我从 Place API 更新标记后用来“刷新”地图的功能之一,希望对您有所帮助~
func addMarkerFrom(places: [Place]) {
for place in places {
if place.user_ratings_total ?? 100 > UInt(100) && place.business_status == "OPERATIONAL" {
if place.types?.contains(where: placeTypesFilter.contains) == false {
DispatchQueue.main.async {
let marker = GMSMarker()
let fetchedPlace = place
let markerIconImage = UIImage(named: "Marker_icon_blue")
marker.position = CLLocationCoordinate2D(latitude: (fetchedPlace.geometry?.location?.latitude)!, longitude: (fetchedPlace.geometry?.location?.longitude)!)
marker.title = place.name
marker.snippet = "\(String(describing: fetchedPlace.user_ratings_total)), \(String(describing: fetchedPlace.rating))"
marker.appearAnimation = .pop
marker.icon = self.drawMarkerWith(image: markerIconImage!, rating: fetchedPlace.rating!, userRatingTool: fetchedPlace.user_ratings_total!)
marker.infoWindowAnchor = CGPoint(x: 0.5, y: 2.3)
marker.tracksInfoWindowChanges = true
marker.map = self.mapView
filteredPlaces.append(fetchedPlace)
}
}
}
}
}
推荐阅读
- sql - SSMS:自动将来自同一 SQL 脚本的多个结果集保存到 Excel 中的单独选项卡中?
- python - 如何在 Python 中编辑 Facebook 帖子?
- amazon-web-services - AWS StepFunctions - 合并和展平与原始输入相结合的任务输出
- tree - 如何在prolog中计算一棵树的叶子?
- .net - 在边缘下载文件的页面名称不是 .net 中的文件名
- flutter - 双飞镖/颤振自动铸造的影响
- python - 检查是否在派生类中重新分配了属性
- docker - 在 Jenkins Pipeline 中访问本地运行的容器
- r - 数字输入到闪亮的数据框
- javascript - 在 d3 中创建螺旋