You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Maps SDK热力图追加数组后无法更新的技术问询

解决SwiftUI中Google Maps热力图不更新的问题

你的核心问题在于updateUIView方法中每次都创建新的GMUHeatmapTileLayer并添加到地图,旧图层并未被移除,同时没有复用已有的图层实例,导致新数据无法正确渲染。此外,标记的添加逻辑也存在重复添加的问题。

修复方案:

  1. 实现Coordinator持久化图层引用
    通过UIViewRepresentable的Coordinator来保存热力图层和标记的实例,避免每次更新时重复创建。

  2. 复用热力图层更新数据
    在makeUIView中初始化热力图层并关联到Coordinator,后续更新时直接修改已有图层的weightedData即可。

  3. 优化标记添加逻辑
    仅在首次创建地图时添加标记,或通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 17:40:31