iOS中为Google Map标记添加地点名称标签的实现方法
嘿,刚好有过类似的实践经验,给你分享两个不用折腾自定义图标的简便实现方案,亲测好用:
方案一:利用GMSMarker的
iconView属性自定义标记视图(最推荐) GMSMarker其实自带了iconView属性,允许你直接传入一个UIView作为标记的显示内容,不用提前把视图转成图片。你可以把标记图标和地点名称Label组合在一个容器View里,直接赋值给iconView就行,地图缩放、移动时,这个View会自动跟着Marker同步位置,完全不用自己处理坐标转换。
举个Swift的实现示例:
// 封装一个生成自定义标记视图的方法 func makeCustomMarkerView(withTitle title: String) -> UIView { // 容器View,根据你的需求调整尺寸 let container = UIView(frame: CGRect(x: 0, y: 0, width: 90, height: 35)) // 添加标记图标(这里用系统图标,你也可以换成自己的自定义图片) let markerImageView = UIImageView(image: UIImage(systemName: "mappin.circle.fill")) markerImageView.frame = CGRect(x: 0, y: 0, width: 30, height: 30) markerImageView.tintColor = .systemRed container.addSubview(markerImageView) // 添加地点名称Label let titleLabel = UILabel(frame: CGRect(x: 35, y: 0, width: 55, height: 30)) titleLabel.text = title titleLabel.font = UIFont.systemFont(ofSize: 12, weight: .medium) titleLabel.textColor = .label titleLabel.numberOfLines = 0 // 支持换行 container.addSubview(titleLabel) return container } // 使用的时候 let marker = GMSMarker(position: CLLocationCoordinate2D(latitude: 31.2304, longitude: 121.4737)) // 给marker设置自定义视图 marker.iconView = makeCustomMarkerView(withTitle: "上海") marker.map = yourMapView
这个方案的优势:
- 完全不用处理图片生成逻辑,直接用UIKit组件组合,调整样式(字体、颜色、换行)都非常灵活
- 标记和标签绑定在一起,地图交互时自动同步位置,不用额外写代码维护坐标
- 支持动态修改Label内容,直接修改
iconView里的Label就行,不用重新生成标记
方案二:直接给地图添加UILabel并同步位置
如果不想修改Marker的图标,也可以直接把UILabel作为子视图添加到GMSMapView上,然后通过坐标转换把经纬度转成屏幕坐标,设置Label的位置。不过这个方法需要监听地图的相机变化,实时更新Label的位置,否则地图移动后Label会错位。
示例代码:
// 给指定Marker添加对应的名称Label func addTitleLabel(to marker: GMSMarker, title: String) { let titleLabel = UILabel() titleLabel.text = title titleLabel.font = UIFont.systemFont(ofSize: 12) titleLabel.backgroundColor = .white.withAlphaComponent(0.8) titleLabel.layer.cornerRadius = 4 titleLabel.clipsToBounds = true titleLabel.sizeToFit() // 将Marker的经纬度转换为地图上的屏幕坐标 let screenPoint = yourMapView.projection.point(for: marker.position) // 把Label放在Marker上方,调整偏移量 titleLabel.center = CGPoint(x: screenPoint.x, y: screenPoint.y - 25) // 设置层级,避免被地图覆盖 titleLabel.layer.zPosition = 100 yourMapView.addSubview(titleLabel) // 把Label和Marker关联起来,方便后续更新位置 marker.userData = titleLabel } // 实现GMSMapViewDelegate的方法,监听地图相机变化,更新所有Label的位置 extension YourViewController: GMSMapViewDelegate { func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) { for marker in mapView.markers { guard let label = marker.userData as? UILabel else { continue } let screenPoint = mapView.projection.point(for: marker.position) label.center = CGPoint(x: screenPoint.x, y: screenPoint.y - 25) } } }
这个方案的注意点:
- 必须实现
GMSMapViewDelegate的didChange position方法,否则地图移动/缩放后Label位置会错误 - 要注意Label的层级,设置
zPosition避免被地图元素覆盖 - 如果Marker数量较多,频繁更新位置可能会有性能损耗,适合Marker数量少的场景
总结
优先推荐方案一,代码量更少,维护成本低,UI调整也更灵活,完全满足你给每个Marker添加地点名称Label的需求。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

