Vista de anotación personalizada en Google Maps SDK

Creé una aplicación para iOS basada en mapas en la que pensé usar el SDK de Google Maps para iOS en lugar de Mapkit. Encontré la documentación, pero no encontré métodos relacionados con la vista de anotación personalizada. ¿Alguien puede proporcionarme la solución sobre cómo crear una vista de anotación personalizada (ventana de información) y cómo agregar contenido (título, fragmento) para ella.

Si marca GMSMapView.h dentro de GoogleMaps.Framework, puede ver el siguiente método que le permitirá agregar una ventana de información personalizada para un marcador, en lugar de usar solo el título estándar y el fragmento:

NOTE que (op) dice annotationView = infoWindow
PERO NORMAL: annotationView = marker en sí y calloutView = infoWindow

/** * Called when a marker is about to become selected, and provides an optional * custom info window to use for that marker if this method returns a UIView. * If you change this view after this method is called, those changes will not * necessarily be reflected in the rendered version. * * The returned UIView must not have bounds greater than 500 points on either * dimension. As there is only one info window shown at any time, the returned * view may be reused between other info windows. * * @return The custom info window for the specified marker, or nil for default */ - (UIView *)mapView:(GMSMapView *)mapView markerInfoWindow:(id)marker; 

No sé ustedes, pero creo que las ventanas de información renderizada de UIView de Google son un poco restrictivas. Usando SMCalloutView y el proyecto de ejemplo de Ryan Maxwell , es posible presentar vistas más interactivas.

Esto funciona en Google Maps SDK v1.8.1, desde 2014-junio-10.

SMCalloutView predeterminado en Google Maps

Primero, configure un poco:

 #import  static const CGFloat CalloutYOffset = 10.0f; @interface ViewController () @property (strong, nonatomic) SMCalloutView *calloutView; @property (strong, nonatomic) UIView *emptyCalloutView; @end 

Inicialice SMCalloutView , agregue un botón y luego cree una UIView vacía:

 - (void)viewDidLoad { /* all your other view init, settings, etc... */ self.calloutView = [[SMCalloutView alloc] init]; self.calloutView.hidden = YES; UIButton *button = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; [button addTarget:self action:@selector(calloutAccessoryButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; self.calloutView.rightAccessoryView = button; self.emptyCalloutView = [[UIView alloc] initWithFrame:CGRectZero]; } 

Tenemos que dibujar esa UIView vacía para satisfacer el SDK de Maps, pero la vista que SMCalloutView es SMCalloutView . También configuré una compensación vertical reutilizable para la vista de llamadas.

Agregue métodos delegates para manejar llamadas a la ventana de información:

 #pragma mark - GMSMapViewDelegate - (UIView *)mapView:(GMSMapView *)mapView markerInfoWindow:(GMSMarker *)marker { CLLocationCoordinate2D anchor = marker.position; CGPoint point = [mapView.projection pointForCoordinate:anchor]; self.calloutView.title = marker.title; self.calloutView.calloutOffset = CGPointMake(0, -CalloutYOffset); self.calloutView.hidden = NO; CGRect calloutRect = CGRectZero; calloutRect.origin = point; calloutRect.size = CGSizeZero; [self.calloutView presentCalloutFromRect:calloutRect inView:mapView constrainedToView:mapView animated:YES]; return self.emptyCalloutView; } - (void)mapView:(GMSMapView *)pMapView didChangeCameraPosition:(GMSCameraPosition *)position { /* move callout with map drag */ if (pMapView.selectedMarker != nil && !self.calloutView.hidden) { CLLocationCoordinate2D anchor = [pMapView.selectedMarker position]; CGPoint arrowPt = self.calloutView.backgroundView.arrowPoint; CGPoint pt = [pMapView.projection pointForCoordinate:anchor]; pt.x -= arrowPt.x; pt.y -= arrowPt.y + CalloutYOffset; self.calloutView.frame = (CGRect) {.origin = pt, .size = self.calloutView.frame.size }; } else { self.calloutView.hidden = YES; } } - (void)mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate { self.calloutView.hidden = YES; } - (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker { /* don't move map camera to center marker on tap */ mapView.selectedMarker = marker; return YES; } 

Manejar los toques en el botón de llamada, aquí usando una vista de alerta con título de marcador y fragmento:

 - (void)calloutAccessoryButtonTapped:(id)sender { if (mapView_.selectedMarker) { GMSMarker *marker = mapView_.selectedMarker; //NSDictionary *userData = marker.userData; UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:marker.title message:marker.snippet delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alertView show]; } } 

Obviamente, asegúrese de que su ViewController (.h) escuche GMSMapViewDelegate:

 @interface ViewController : UIViewController  

Y eso debería funcionar básicamente. Para obtener un proyecto completo de xcode, vea el ejemplo mencionado anteriormente de Ryan Maxwell.