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

Swift开发:移动Google Map时隐藏GMS Marker的info window方法

实现方案(iOS Google Maps SDK)
  • 先在地图控制器中声明属性,跟踪自定义InfoWindow的展示状态
// 记录当前正在展示的自定义InfoWindow实例
var currentShownInfoWindow: UIView?
// 标记InfoWindow是否处于展示状态
var isInfoWindowShown = false
  • 实现GMSMapView的mapView:willMove:代理方法,该方法会在地图开始被拖动时立刻触发,刚好满足立刻隐藏的需求
func mapView(_ mapView: GMSMapView, willMove gesture: Bool) {
    guard isInfoWindowShown else { return }
    // 移除当前展示的自定义InfoWindow
    currentShownInfoWindow?.removeFromSuperview()
    currentShownInfoWindow = nil
    isInfoWindowShown = false
    // 可选:如果需要同步取消Marker的选中状态,添加这行代码
    mapView.selectedMarker = nil
}
  • 自定义InfoWindow展示逻辑注意点
    不要将自定义View绑定到Marker上,直接添加到控制器视图层级,避免天然跟随Marker移动:
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
    // 先移除之前残留的InfoWindow
    currentShownInfoWindow?.removeFromSuperview()
    
    // 初始化你自己的自定义InfoWindow视图
    let customInfoWindow = CustomInfoWindowView()
    // 设置尺寸为屏幕上半部分,位置可根据需求调整
    customInfoWindow.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height / 2)
    
    // 直接添加到当前控制器的view上,不要关联到Marker
    view.addSubview(customInfoWindow)
    
    // 保存当前状态
    currentShownInfoWindow = customInfoWindow
    isInfoWindowShown = true
    
    // 返回true拦截系统默认的InfoWindow展示逻辑
    return true
}
实现方案(Android Google Maps SDK)
  • 先在页面中声明变量跟踪InfoWindow状态
// 记录当前展示的自定义InfoWindow实例
private var currentInfoWindow: View? = null
// 标记InfoWindow是否处于可见状态
private var isInfoWindowVisible = false
  • 监听地图相机移动开始事件,触发时立刻隐藏InfoWindow
googleMap.setOnCameraMoveStartedListener { reason ->
    if (!isInfoWindowVisible) return@setOnCameraMoveStartedListener
    // 从父布局移除当前的InfoWindow
    (currentInfoWindow?.parent as? ViewGroup)?.removeView(currentInfoWindow)
    currentInfoWindow = null
    isInfoWindowVisible = false
    // 可选:同步取消Marker的选中状态
    googleMap.selectedMarker = null
}
  • 自定义InfoWindow展示逻辑注意点
    不要使用系统默认的InfoWindow适配器,直接将自定义布局添加到地图的父布局层级:
googleMap.setOnMarkerClickListener { marker ->
    // 先移除之前残留的InfoWindow
    currentInfoWindow?.let {
        (it.parent as? ViewGroup)?.removeView(it)
    }
    
    // 加载你自己的自定义InfoWindow布局
    val customInfoWindow = layoutInflater.inflate(R.layout.custom_info_window, null)
    // 设置尺寸为屏幕上半部分,位置可根据需求调整
    val params = FrameLayout.LayoutParams(
        ViewGroup.LayoutParams.MATCH_PARENT,
        resources.displayMetrics.heightPixels / 2
    )
    customInfoWindow.layoutParams = params
    
    // 添加到地图所在的父布局中
    mapParentLayout.addView(customInfoWindow)
    
    // 保存当前状态
    currentInfoWindow = customInfoWindow
    isInfoWindowVisible = true
    
    // 返回true拦截系统默认的InfoWindow展示逻辑
    true
}

注:上述方案均选择「相机开始移动」的回调而非移动结束回调,就是为了满足地图被移动时立刻隐藏的要求,不会出现InfoWindow跟随Marker移动一段距离才消失的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 12:42:04