2013-03-04 8 views
10

Attualmente sto creando e restituendo una vista personalizzata con google maps ios SDK impostando delegato su self e utilizzando il seguente codice.Aggiungi pulsanti per visualizzare restituito da markerInfoWindow metodo delegato

#pragma mark - GMSMapViewDelegate 
-(UIView*)mapView:(GMSMapView *)mapView markerInfoWindow:(id<GMSMarker>)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<GMSMarker>)marker { 
    NSLog(@"Tap Captured"); 
} 

Il didTapWindowOfMarker è essere licenziato Quando si tocca la visualizzazione personalizzata, ma nessuno dei metodi di riferimento per i pulsanti vengono licenziati.

Qualche idea sul perché questo potrebbe essere?

+0

si può si prega di inviare la vostra soluzione come sto lottando con lo stesso problema –

risposta

21

Forse, come detto ufficialmente nella documentazione di Google Maps Android API, la restrizione sotto per quanto riguarda infowindows vale per Google Maps per iOS SDK anche:

finestra

Info non è un Live View, piuttosto la vista è reso come un'immagine sulla mappa. Di conseguenza, tutti gli ascoltatori impostati sulla visualizzazione vengono ignorati e non è possibile distinguere tra gli eventi di clic in varie parti della vista. Si consiglia di non inserire componenti interattivi, come pulsanti, caselle di controllo o input di testo, nella finestra delle informazioni personalizzate.

Quindi, in pratica cliccando su qualsiasi parte del infowindow attiverà solo "didTapWindowOfMarker"

+3

ho trovato il sopra per essere il caso e invece optato per implementare - (BOOL) mapView: (GMSMapView *) indicatore mapView didTapMarker: (id ); e restituire SI; all'interno di tale metodo tale che la risposta per la selezione di un marcatore non ha usato la finestra informativa, ma ha invece utilizzato la mia soluzione. Grazie per le informazioni aggiuntive! – ercmcd

+2

e muovi la tua soluzione quando la mappa si muove? –

+2

@ercmcd puoi postare la tua soluzione perché sto lottando con lo stesso problema –

1

UPDATE:

Ecco il codice che uso al fine di rilevare toccare tasti aggiunti ai miei infoWindows . Creo un infoWindow personalizzato con 2 pulsanti falsi (potrebbero effettivamente essere sostituiti da immagini perché non attivano alcuna azione) e aggiungo un overlay completamente trasparente con 2 pulsanti reali su infoWindow. Questi pulsanti attiveranno le azioni.

E utilizzo alcuni metodi delegati o KVC per spostare l'overlay quando viene spostata la stessa informazione.

- (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<falseButtons.count; i++) { 
     UIButton *falseButton = [falseButtons objectAtIndex:i]; 
     UIButton *activableButton = [actionButtons objectAtIndex:i]; 
     [falseButton setFrame:CGRectMake(currentOffset, 0, buttonWidth, contentView.frame.size.height)]; 
     currentOffset += buttonWidth; 
     activableButton.frame = falseButton.frame; 
     [activableButton setTitle:@"" forState:UIControlStateNormal]; 
     [self.actionOverlayCalloutView addSubview:activableButton]; 
     [contentView addSubview:falseButton]; 
    } 
    [calloutView addSubview:contentView]; 

    CLLocationCoordinate2D anchor = [self.mapView.selectedMarker position]; 
    CGPoint point = [self.mapView.projection pointForCoordinate:anchor]; 
    point.y -= self.mapView.selectedMarker.icon.size.height + offset/2 + (infoWindowHeight - offset/2)/2; 
    self.actionOverlayCalloutView.center = point; 

    [self.mapView addSubview:self.actionOverlayCalloutView]; 
    return calloutView; 
} 

- (void)mapView:(GMSMapView *)pMapView didChangeCameraPosition:(GMSCameraPosition *)position { 
    if (pMapView.selectedMarker != nil && self.actionOverlayCalloutView.superview) { 
     CLLocationCoordinate2D anchor = [self.mapView.selectedMarker position]; 
     CGPoint point = [self.mapView.projection pointForCoordinate:anchor]; 
     float offset = anchorSize * M_SQRT2; 
     point.y -= self.mapView.selectedMarker.icon.size.height + offset/2 + (infoWindowHeight - offset/2)/2; 
     self.actionOverlayCalloutView.center = point; 
    } else { 
     [self.actionOverlayCalloutView removeFromSuperview]; 
    } 
} 

- (void)mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate { 
    [self.actionOverlayCalloutView removeFromSuperview]; 
} 

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 
    if ([keyPath isEqualToString:@"mapView.selectedMarker"]) { 
     if (!self.mapView.selectedMarker) { 
      [self.actionOverlayCalloutView removeFromSuperview]; 
     } 
    } 
} 

- (void)onButton2Clicked { 
    //your code 
    self.mapView.selectedMarker = nil; 
} 

- (void)onButton1Clicked { 
    // your code; 
    self.mapView.selectedMarker = nil; 
} 

EX POST:

Date un'occhiata a questa discussione e in particolare alla # 9, dovrebbe essere utile https://code.google.com/p/gmaps-api-issues/issues/detail?id=4961

+0

Mentre questo link può rispondere alla domanda, è meglio includere le parti essenziali della risposta [qui] (http: //meta.stackexchange. it/a/8259) e fornire il link per riferimento. Le risposte di solo collegamento possono diventare non valide se la pagina collegata cambia. – bummi

2

Ho un uview e sto aggiungendo un delegato al visualizzare in modo che un UIButton chiama un selettore. Per la mappa di google, non faccio nulla quando chiamo

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

Tuttavia, ho impostato il mio infowindow (la mia vista personalizzata) delega ad auto, e chiamare tutte le mie azioni, quando si preme il pulsante che è legato alla selettore.

+2

Salve, l'azione del pulsante viene attivata per un tocco in qualsiasi punto della finestra di informazioni personalizzate o solo un pulsante dell'interfaccia utente al suo interno? Se solo l'UIButton, allora potresti incollare il codice. – vkinra

-1

1) Creare una visualizzazione secondaria che si desidera visualizzare in InfoWindow.

2) Impostare la cornice della sottoview equivale al frame della vista InfoWindow.

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

Swift 3.0 Soluzione

//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() 
     } 

I have added customInfoWindow like this

e fare presa di questa visione (customInfoWindow) a stesso controllore che ha mapview.

ho avuto l'idea da questo link grazie a questo sviluppatore Custom and interactive googlemaps(IOS SDK) infowindow

Problemi correlati