谷歌地图的自定义信息窗口
Posted
技术标签:
【中文标题】谷歌地图的自定义信息窗口【英文标题】:Custom Info Window for Google Maps 【发布时间】:2013-05-20 18:01:49 【问题描述】:我想为 ios 版 Google 地图制作一个自定义信息窗口,如下图所示。是否可以像 GMSMarker、GMSPolyline 和 GMSPolygon 那样扩展 GMSOverlay 来创建自定义图形?
【问题讨论】:
自定义信息窗口(== 点击窗口)或自定义标记(==始终存在)? kevinxh.github.io/swift/… 这个博客解释了如何解决这个问题。 请标记已接受的答案。 【参考方案1】:您将需要使用markerInfoWindow
委托方法以及设置infoWindowAnchor
。
创建标记时,设置锚点:
GMSMarker *marker = [[GMSMarker alloc] init];
marker.position = MARKER_POSITION;
marker.infoWindowAnchor = CGPointMake(0.44f, 0.45f);
marker.icon = [UIImage imageNamed:@"CustomMarkerImageName"];
然后创建委托方法:
- (UIView *)mapView:(GMSMapView *)mapView markerInfoWindow:(GMSMarker *)marker
InfoWindow *view = [[[NSBundle mainBundle] loadNibNamed:@"InfoWindow" owner:self options:nil] objectAtIndex:0];
view.name.text = @"Place Name";
view.description.text = @"Place description";
view.phone.text = @"123 456 789";
view.placeImage.image = [UIImage imageNamed:@"customPlaceImage"];
view.placeImage.transform = CGAffineTransformMakeRotation(-.08);
return view;
在上面的示例中,我创建了一个 xib
然后我加载了那个xib,返回了结果UIView
。相反,您可以只使用代码来构造 UIView
。
【讨论】:
skarE,您是否还必须制作相应的 InfoWindow 类?是否可以获得您制作的 XIB 文件的副本?谢谢! 我用这个做了一个 UIButton..但是不能点击它 你能把xib文件发给我吗? @RahulMishra 信息窗口是 UIView 的渲染版本,这就是视图无法识别用户交互的原因 信息窗口渲染在地图上如何更新数据?【参考方案2】:对于那些试图将按钮添加到表示信息窗口的自定义视图的人 - 这似乎是不可能的,因为 Google Maps SDK 将其绘制为图像或类似的东西。但是有一个非常简单的解决方案:
-
您必须创建一个自定义视图,其中包含按钮以及您需要在信息窗口中显示的任何内容。
将其作为子视图添加到您的 mapView(mapView: GMSMapView, didTapMarker marker: GMSMarker) 方法中。您可以通过在 mapView.projection.pointForCoordinate(marker.position) 的帮助下获取点击的标记坐标来设置自定义视图的位置
您的自定义视图可能必须通过跟随相机位置来更改其位置,因此您必须处理 mapView(mapView: GMSMapView, didChangeCameraPosition position: GMSCameraPosition) ,您可以轻松地更新自定义视图位置。
var infoWindow = CustomInfoView()
var activePoint : POIItem?
func mapView(mapView: GMSMapView, didTapMarker marker: GMSMarker) -> Bool
if let poiItem = marker as? POIItem
// Remove previously opened window if any
if activePoint != nil
infoWindow.removeFromSuperview()
activePoint = nil
// Load custom view from nib or create it manually
// loadFromNib here is a custom extension of CustomInfoView
infoWindow = CustomInfoView.loadFromNib()
// Button is here
infoWindow.testButton.addTarget(self, action: #selector(self.testButtonPressed), forControlEvents: .AllTouchEvents)
infoWindow.center = mapView.projection.pointForCoordinate(poiItem.position)
activePoint = poiItem
self.view.addSubview(infoWindow)
return false
func mapView(mapView: GMSMapView, didChangeCameraPosition position: GMSCameraPosition)
if let tempPoint = activePoint
infoWindow.center = mapView.projection.pointForCoordinate(tempPoint.position)
【讨论】:
还会显示默认信息窗口。以及如何在指向点击标记的自定义信息上显示指示器。 @RajAggrawal 请问POIItem
是什么@
@King 例如,您的包装类可能包含坐标和名称。它必须是 GMSMarker 的子类。看看here
工具提示有自己的白色背景。我可以说清楚吗?因为我已经尝试过,但似乎没有任何效果
我想它应该像您添加到 ViewController 视图中的常规子视图一样工作,但我目前无法检查。【参考方案3】:
您可以将这种类型的 UIImage 作为图标传递,如下所示
CLLocationCoordinate2D position = CLLocationCoordinate2DMake(latitude,longitude);
GMSMarker *location = [GMSMarker markerWithPosition:position];
location.title = @"Location Name";
location.icon = [UIImage imageNamed:@"marker_icon.png"];
location.map = mapView_;
更多详情see this Documentation。
如果您在按下标记后想要这种类型的图像,那么您必须有两种类型的图像。
仅第一个图像标记图标。
第二张图片是带有地点细节的标记。
mapView 初始化时加载的标记图标,如上面的代码。
第二个图像标记和位置细节,你必须像这样在标记内部加载 delegate
方法,使用 For-Loop
和 NSMutablearray
通过检查 marker.title
来知道哪个标记被按下。
- (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker
【讨论】:
是的,我已经看到了,但我希望在用户触摸标记时自定义整个信息窗口。 查看更新的答案@jspooner【参考方案4】:Swift 版本,标记自定义类的示例版本:
class CustomMarker: UIView
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var seperator: UIImageView!
@IBOutlet weak var icon: UIImageView!
@IBOutlet weak var descriptionLabel: UILabel!
class func instanceFromNib() -> UIView
return UINib(nibName: "CustomMarker", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as! UIView
感谢How to initialise a UIView Class with a xib file in Swift, iOS,您可以向 UIView 添加扩展,因此您不需要强制转换
protocol UIViewLoading
extension UIView : UIViewLoading
extension UIViewLoading where Self : UIView
// note that this method returns an instance of type `Self`, rather than UIView
static func loadFromNib() -> Self
let nibName = "\(self)".characters.split$0 == ".".map(String.init).last!
let nib = UINib(nibName: nibName, bundle: nil)
return nib.instantiateWithOwner(self, options: nil).first as! Self
在你的委托中:
func mapView(mapView: GMSMapView, markerInfoWindow marker: GMSMarker) -> UIView?
let customMarker:CustomMarker = CustomMarker.loadFromNib()
customMarker.titleLabel.text = marker.title
customMarker.descriptionLabel.text = marker.snippet
return customMarker
【讨论】:
以上是关于谷歌地图的自定义信息窗口的主要内容,如果未能解决你的问题,请参考以下文章
当你从谷歌地图API中点击地图中的内置位置(不是标记)时,如何自定义弹窗的内容?
为 Android 显示自定义信息窗口 Android 地图实用程序库
带有两个可点击按钮或 ImageView 的 Google 地图 v2 自定义信息窗口