Google Maps SDK热力图追加数组后无法更新的技术问询
解决SwiftUI中Google Maps热力图不更新的问题
你的核心问题在于updateUIView方法中每次都创建新的GMUHeatmapTileLayer并添加到地图,旧图层并未被移除,同时没有复用已有的图层实例,导致新数据无法正确渲染。此外,标记的添加逻辑也存在重复添加的问题。
修复方案:
实现Coordinator持久化图层引用
通过UIViewRepresentable的Coordinator来保存热力图层和标记的实例,避免每次更新时重复创建。复用热力图层更新数据
在makeUIView中初始化热力图层并关联到Coordinator,后续更新时直接修改已有图层的weightedData即可。优化标记添加逻辑
仅在首次创建地图时添加标记,或通过Coordinator控制标记的更新,避免重复添加。
修改后的GoogleMapsView代码:
import SwiftUI import GoogleMaps import GoogleMapsUtils struct GoogleMapsView: UIViewRepresentable { @ObservedObject var locationManager = LocationManager() @Binding var heatmapWeightedData: [GMUWeightedLatLng] // 定义Coordinator持有热力图层和标记 class Coordinator: NSObject { var heatmapLayer: GMUHeatmapTileLayer? var userMarker: GMSMarker? } func makeCoordinator() -> Coordinator { Coordinator() } func makeUIView(context: Context) -> GMSMapView { let camera = GMSCameraPosition.camera(withLatitude: locationManager.latitude, longitude: locationManager.longitude, zoom: 15) let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera) // 初始化热力图层并关联到Coordinator let heatmapLayer = GMUHeatmapTileLayer() heatmapLayer.radius = 150 heatmapLayer.weightedData = heatmapWeightedData heatmapLayer.map = mapView context.coordinator.heatmapLayer = heatmapLayer // 初始化用户标记并关联到Coordinator let userMarker = GMSMarker() userMarker.position = CLLocationCoordinate2D(latitude: locationManager.latitude, longitude: locationManager.longitude) userMarker.title = "My location" userMarker.map = mapView context.coordinator.userMarker = userMarker return mapView } func updateUIView(_ mapView: GMSMapView, context: Context) { // 更新用户标记位置 if let userMarker = context.coordinator.userMarker { userMarker.position = CLLocationCoordinate2D(latitude: locationManager.latitude, longitude: locationManager.longitude) } // 更新热力图层数据(复用已有图层) if let heatmapLayer = context.coordinator.heatmapLayer { heatmapLayer.weightedData = heatmapWeightedData } mapView.animate(toLocation: CLLocationCoordinate2D(latitude: -33.86, longitude: 151.20)) } }
额外说明:
- 原代码中
GoogleMapsView内部的locationManager是每次创建视图时新建的实例,如果你的LocationManager是全局或共享的,建议改为通过外部传入(比如用@ObservedObject或@EnvironmentObject),避免重复实例化。 addTrashLocation方法中追加数据的逻辑是正确的,因为@State变量的修改会触发视图更新,进而调用updateUIView。
内容的提问来源于stack exchange,提问作者RocketBlaster05
相关产品推荐
相关产品推荐

