Google地图的自定义信息窗口

时间:2013-05-25 05:32:04

标签: google-maps-sdk-ios

我想为Google Maps for iOS制作一个自定义信息窗口,如下图所示。是否有可能像GMSMarker,GMSPolyline和GMSPolygon那样扩展GMSOverlay以创建自定义图形?

enter image description here

4 个答案:

答案 0 :(得分:105)

您需要使用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 enter image description here 然后我加载了xib,返回结果UIView。您可以使用代码构建UIView

答案 1 :(得分:7)

对于那些试图将按钮添加到代表信息窗口的自定义视图的人来说 - 似乎无法做到,因为Google Maps SDK会将其绘制为图像或类似内容。但是有一个非常简单的解决方案:

  1. 您必须创建一个自定义视图,其中包含按钮以及您需要在信息窗口中显示的内容。
  2. mapView(mapView:GMSMapView,didTapMarker marker:GMSMarker)方法中将其添加为子视图。您可以通过在 mapView.projection.pointForCoordinate(marker.position)
  3. 的帮助下获取标记坐标来设置自定义视图的位置
  4. 您的自定义视图可能需要按照摄像头位置更改位置,因此您必须处理 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)
        }
    
    }
    

答案 2 :(得分: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初始化时加载标记图标,如上面的代码。

带有地方详细信息的第二个图片标记,您必须使用delegateFor-Loop方法在标记内按NSMutablearray方法加载,方法是检查marker.title以了解按下了哪个标记

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

 }

答案 3 :(得分:2)

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
}