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
相关产品推荐
相关产品推荐

