Agregar botones para ver devueltos por el método de delegado markerInfoWindow

Actualmente estoy creando y devolviendo una vista personalizada con el SDK ios de google maps configurando delegate en self y usando el siguiente código.

#pragma mark - GMSMapViewDelegate -(UIView*)mapView:(GMSMapView *)mapView markerInfoWindow:(id)marker { int popupWidth = 200; int contentWidth = 180; int contentPad = 10; int popupHeight = 140; int popupBottomPadding = 16; int popupContentHeight = popupHeight - popupBottomPadding; int buttonHeight = 30; UIView *outerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, popupWidth, popupHeight)]; UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, popupWidth, popupContentHeight)]; [view setBackgroundColor:[UIColor whiteColor]]; UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(contentPad, 0, contentWidth, 22)]; [titleLabel setFont:[UIFont systemFontOfSize:17.0]]; titleLabel.text = [marker title]; UILabel *descriptionLabel = [[UILabel alloc] initWithFrame:CGRectMake(contentPad, 24, contentWidth, 20)]; [descriptionLabel setFont:[UIFont systemFontOfSize:11.0]]; descriptionLabel.text = [marker snippet]; [view addSubview:titleLabel]; [view addSubview:descriptionLabel]; UIButton *directionButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; directionButton.frame = CGRectMake(contentPad, 45, contentWidth, buttonHeight); [directionButton setTitle:@"Directions" forState:UIControlStateNormal]; [directionButton addTarget:self action:@selector(directionsPressed) forControlEvents:UIControlEventTouchDown]; UIButton *viewLocationButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [viewLocationButton addTarget:self action:@selector(viewLocationPressed) forControlEvents:UIControlEventTouchUpInside]; [viewLocationButton setTitle:@"View Location" forState:UIControlStateNormal]; viewLocationButton.frame = CGRectMake(contentPad, 80, contentWidth, buttonHeight); // handle bottom dealio UIImage *bottomImage = [UIImage imageNamed:@"map-pointer-bottom"]; UIImageView *bottomView = [[UIImageView alloc] initWithFrame:CGRectMake((popupWidth / 2) - (bottomImage.size.width / 2), (popupContentHeight), bottomImage.size.width, bottomImage.size.height)]; [bottomView setImage:bottomImage]; [outerView addSubview:view]; [outerView addSubview:bottomView]; [outerView addSubview:directionButton]; [outerView addSubview:viewLocationButton]; ListItem *li = (ListItem*)[marker userData]; self.currentItem = li; NSLog(@"List Item %@ - %@", li.type, li.typeid); return outerView; } -(void)directionsPressed { NSLog(@"Directions Pressed"); } -(void)viewLocationPressed { NSLog(@"Location View Pressed"); } - (void)mapView:(GMSMapView *)mapView didTapInfoWindowOfMarker:(id)marker { NSLog(@"Tap Captured"); } 

DoTapWindowOfMarker se activa cuando toco la vista personalizada, pero ninguno de los métodos de destino de los botones se activan.

¿Alguna idea de por qué esto podría ser?

Posiblemente, como se menciona oficialmente en la documentación de Google Maps Android API, la restricción a continuación relacionada con infowindows se aplica al SDK de iOS de Google Maps también:

La ventana de información no es una vista en vivo, sino que la vista se representa como una imagen en el mapa. Como resultado, no se tienen en cuenta los oyentes que establece en la vista y no puede distinguir entre los eventos de clic en varias partes de la vista. Se le recomienda no colocar componentes interactivos, como botones, casillas de verificación o entradas de texto, en su ventana de información personalizada.

Así que, básicamente, al hacer clic en cualquier parte de la ventana de información se activará solo ” didTapWindowOfMarker

Solución Swift 3.0

  //empty the default infowindow func mapView(_ mapView: GMSMapView, markerInfoWindow marker: GMSMarker) -> UIView? { return UIView() } // reset custom infowindow whenever marker is tapped func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool { customInfoView.removeFromSuperview() // customInfoView.button.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside) self.view.addSubview(customInfoView) // Remember to return false // so marker event is still handled by delegate return false } // let the custom infowindow follows the camera func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) { if (locationMarker != nil){ let location = locationMarker.position customInfoView.center = mapView.projection.point(for: location) } } // take care of the close event func mapView(_ mapView: GMSMapView, didTapAt coordinate: CLLocationCoordinate2D) { customInfoView.removeFromSuperview() } 

He agregado customInfoWindow como este

y haga la salida de esta vista (customInfoWindow) en el mismo controlador que tiene mapView.

Obtuve la idea de este enlace gracias a este desarrollador Infowindow personalizado e interactivo googlemaps (IOS SDK)

Tengo una vista UV y estoy agregando un delegado a la vista para que un UIButton llame a un selector. Para el mapa de google, no hago nada cuando llamo

 - (void) mapView:(GMSMapView *)mapView didTapInfoWindowOfMarker:(GMSMarker *)marker; 

Sin embargo, configuro mi infowindow (mi vista personalizada) como delegado, y llamo a todas mis acciones cuando presiono el botón que está vinculado al selector.

ACTUALIZAR:

Aquí está el código que uso para detectar los botones agregados a mi información de Windows. Creo una ventana de información personalizada con 2 botones falsos (en realidad podrían reemplazarse por imágenes porque no activarán ninguna acción) y agrego una superposición completamente transparente con 2 botones reales sobre la ventana de información. Estos botones activarán las acciones.

Y uso algunos métodos de delegado o KVC para mover la superposición cuando se mueve la ventana de información.

 - (UIView *)mapView:(GMSMapView *)mapView markerInfoWindow:(GMSMarker *)marker { [self.actionOverlayCalloutView removeFromSuperview]; UIView *calloutView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, infoWindowWidth, infoWindowHeight)]; float offset = anchorSize * M_SQRT2; CGAffineTransform rotateBy45Degrees = CGAffineTransformMakeRotation(M_PI_4); UIView *arrow = [[UIView alloc] initWithFrame:CGRectMake((infoWindowWidth - anchorSize)/2.0, infoWindowHeight - offset, anchorSize, anchorSize)]; arrow.transform = rotateBy45Degrees; arrow.backgroundColor = [UIColor lightGrayColor]; [calloutView addSubview:arrow]; UIView *contentView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, infoWindowWidth, infoWindowHeight - offset/2)]; [contentView setBackgroundColor:[UIColor whiteColor]]; contentView.layer.cornerRadius = 5; contentView.layer.masksToBounds = YES; contentView.layer.borderColor = [UIColor lightGrayColor].CGColor; contentView.layer.borderWidth = 1.0f; self.actionOverlayCalloutView = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:contentView]]; //hack to copy a view... self.actionOverlayCalloutView.backgroundColor = [UIColor lightGrayColorWithAlpha:0.5]; self.actionOverlayCalloutView.layer.cornerRadius = 5; NSMutableArray *falseButtons = [NSMutableArray array]; NSMutableArray *actionButtons = [NSMutableArray array]; PointMapItem *pointAnnotation = marker.userData; if ([pointAnnotation canPerformSend]) { UIButton *button = [[UIButton alloc] init]; [button setImage:[UIImage imageNamed:@"imageButton1.png"] forState:UIControlStateNormal]; [falseButtons addObject:button]; UIButton *activableButton = [[UIButton alloc] init]; [activableButton addTarget:self action:@selector(onButton1Clicked) forControlEvents:UIControlEventTouchUpInside]; [actionButtons addObject:activableButton]; } if ([pointAnnotation canPerformShowDetails]) { UIButton *button = [[UIButton alloc] init]; [button setImage:[UIImage imageNamed:@"imageButton1.png"] forState:UIControlStateNormal]; [falseButtons addObject:button]; UIButton *activableButton = [[UIButton alloc] init]; [activableButton addTarget:self action:@selector(onButton2Clicked) forControlEvents:UIControlEventTouchUpInside]; [actionButtons addObject:activableButton]; } int buttonWidth = contentView.frame.size.width / [falseButtons count]; int currentOffset = 0; for (int i=0; i 

ANTIGUO POST:

Eche un vistazo a este hilo y específicamente al # 9, debería ser útil https://code.google.com/p/gmaps-api-issues/issues/detail?id=4961

1) Cree una subvista que quiera mostrar en infoWindow.

2) Establecer el marco de la subvista igual al marco de la vista de infoWindow.

  [subView setFrame:infoview.frame]; subView = [[[NSBundle mainBundle] loadNibNamed:@"viewName" owner:self options:nil] objectAtIndex:0]; [self.mapview addSubview:subView];