Google地图的自定义信息窗口

我想为iOS版Google地图制作自定义信息窗口,如下图所示。 是否可以像GMSMarker,GMSPolyline和GMSPolygon那样扩展GMSOverlay来创build自定义graphics?

在这里输入图像描述

对于那些试图在代表信息窗口的自定义视图中添加button的人来说 – 这似乎是不可能的,因为Google Maps SDK将其绘制为图像或类似的东西。 但是有一个相当简单的解决scheme:

  1. 您必须使用button创build自定义视图,以及需要在信息窗口中显示的任何视图。
  2. 把它作为子视图添加到你的mapView(mapView:GMSMapView,didTapMarker标记:GMSMarker)中 。 您可以通过在mapView.projection.pointForCoordinate(marker.position)的帮助下获取标记的坐标来设置自定义视图的位置。
  3. 您的自定义视图可能必须通过跟随摄像头位置来改变它的位置,所以您必须处理mapView(mapView:GMSMapView,didChangeCameraPosition位置: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) } } 

您将要使用markerInfoWindow委托方法,并设置infoWindowAnchor

当您创build标记时,请设置锚点:

 GMSMarker *marker = [[GMSMarker alloc] init]; marker.position = MARKER_POSITION; marker.infoWindowAnchor = CGPointMake(0.44f, 0.45f); marker.icon = [UIImage imageNamed:@"CustomMarkerImageName"]; 

然后创build委托方法:

 - (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; } 

在上面的例子中,我创build了一个xib 在这里输入图像描述 和我加载该xib,返回结果UIView 。 你可以用代码来构build一个UIView

你可以像下面这样将这种types的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_; 

有关更多信息, 请参阅此文档 。

如果您想在按下标记之后想要这种types的图像,则必须有两种types的单个图像。

只有第一个图像标记图标。

第二个图像是地方细节的标记。

当mapView像上面的代码初始化时加载的标记图标。

和第二个图像标记与地方的细节,你必须加载像这样的内部标记按下delegate方法使用For-LoopNSMutablearray通过检查marker.title知道哪个标记被按下。

  - (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker { } 

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 }} 

感谢如何在Swift中用xib文件初始化一个UIView类,你可以在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 }