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

GMSMarker信息窗数据不更新:如何无需重建实现内容更新

解决GMSMarker信息窗无闪烁更新问题

核心问题在于你当前每次更新都重建信息窗视图,导致闪烁。要实现无刷新更新,需要复用已创建的信息窗视图并直接修改其数据,而非重新创建。

步骤1:让MyInfoView支持动态数据绑定

修改你的SwiftUI信息窗视图,将posTime改为可绑定的状态变量,这样数据变化时视图会自动刷新:

struct MyInfoView: View {
    let device: Device // 保留原有设备参数
    @State var posTime: CLong // 改为@State变量支持动态更新

    var body: some View {
        // 原有视图布局,确保使用posTime渲染内容
        // 示例:Text("时间:\(posTime)")
    }
}

步骤2:复用信息窗的HostingController

修改信息窗创建逻辑,将已创建的UIHostingController和标记的tranId一起存储到marker的userData中,避免重复创建:

func mapView(_ mapView: GMSMapView, markerInfoWindow marker: GMSMarker) -> UIView? {
    // 检查是否已有缓存的HostingController
    if let cachedData = marker.userData as? (tranId: String, hostingController: UIHostingController<MyInfoView>) {
        return cachedData.hostingController.view
    }

    let posTime = CLong(marker.title ?? "0") ?? 0
    let frame = CGRect(x: 0, y: 0, width: 150, height: 140)
    
    let infoView = MyInfoView(device: device, posTime: posTime)
    let hostingController = UIHostingController(rootView: infoView)
    hostingController.view.frame = frame
    hostingController.view.backgroundColor = .clear

    // 缓存tranId和HostingController到userData
    marker.userData = (marker.userData as! String, hostingController)
    
    return hostingController.view
}

步骤3:直接更新信息窗数据并触发刷新

在updateMarker方法中,直接修改已缓存的MyInfoView的posTime,并调用marker的刷新方法通知地图更新信息窗:

private func updateMarker(index: Int, markerData: MarkerData, select: Bool) {
    let marker = markersOnMap[index]
    marker.title = markerData.time.description
    
    if marker.hasChangedPosition(markerData: markerData) {
        marker.position = markerData.getPosition()
        UIImpactFeedbackGenerator(style: .heavy).impactOccurred()
    }
    
    // 更新选中标记的信息窗
    if select, let cachedData = marker.userData as? (tranId: String, hostingController: UIHostingController<MyInfoView>) {
        // 直接修改视图的posTime
        cachedData.hostingController.rootView.posTime = CLong(markerData.time.description) ?? 0
        // 通知Google Maps更新信息窗显示
        marker.setNeedsInfoWindowUpdate()
    }
}

关键说明

  • 确保标记的tracksInfoWindowChanges已设为true(你在addMarker中已经设置),这是地图能响应信息窗更新的前提。
  • 此方案复用了已创建的视图实例,避免了销毁重建带来的闪烁,同时利用SwiftUI的状态绑定自动刷新视图内容。

内容的提问来源于stack exchange,提问作者Andrija Randjelovic

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 06:26:33