2013-03-04 4 views
10

Ich erstelle zurzeit eine benutzerdefinierte Ansicht mit dem Google Maps-ios-SDK und gebe sie zurück, indem ich delegate auf self setze und den folgenden Code verwende.Hinzufügen von Schaltflächen, die von der markerInfoWindow-Delegatmethode zurückgegeben werden

#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"); 
} 

Die didTapWindowOfMarker wird gefeuert, wenn ich die benutzerdefinierte Ansicht tippen, aber weder der Ziel Methoden für die Schaltflächen abgefeuert werden.

Irgendwelche Ideen, warum dies sein könnte?

+0

Sie bitte Ihre Lösung veröffentlicht, sobald ich mit dem gleichen Problem bin zu kämpfen –

Antwort

21

Möglicherweise als offiziell in der Dokumentation von Google Maps Android API genannt, die unter Einschränkung in Bezug auf Infofenster gilt für Google Maps iOS SDK auch:

Info-Fenster ist nicht live, sondern die Ansicht, wie gemacht wird ein Bild auf die Karte. Daher werden alle Listener ignoriert, die Sie in der Ansicht festgelegt haben, und Sie können nicht zwischen Klickereignissen in verschiedenen Teilen der Ansicht unterscheiden. Es wird empfohlen, keine interaktiven Komponenten wie Schaltflächen, Kontrollkästchen oder Texteingaben in das benutzerdefinierte Informationsfenster einzufügen.

So klicken grundsätzlich auf einem beliebigen Teil des Infofenster auslösen wird nur „didTapWindowOfMarker

+3

ich die oben der Fall zu sein und stattdessen entschieden gefunden zu implementieren - (BOOL) mapView: (GMSMapView *) Kartenansicht didTapMarker: (id ) marker; und gib JA zurück; innerhalb dieser Methode, so dass die Antwort zum Auswählen einer Markierung das Informationsfenster überhaupt nicht verwendete, sondern stattdessen meine eigene Lösung verwendete. Danke für die zusätzlichen Informationen! – ercmcd

+2

und Sie bewegen Ihre Lösung, wenn sich die Karte bewegt? –

+2

@ercmcd können Sie bitte Ihre Lösung posten, wie ich mit dem gleichen Problem kämpfen –

1

UPDATE:

Hier ist der Code, den ich nutzen, um tippen Sie auf Tasten hinzugefügt, um meine Infofenster zu erkennen . Ich erstelle ein benutzerdefiniertes InfoWindow mit 2 falschen Buttons (sie könnten tatsächlich durch Bilder ersetzt werden, weil sie keine Aktion auslösen) und ich füge ein völlig transparentes Overlay mit 2 echten Buttons über das InfoWindow hinzu. Diese Schaltflächen lösen die Aktionen aus.

Und ich verwende ein paar Delegate Methoden oder KVC, um das Overlay zu verschieben, wenn das InfoWindow selbst verschoben wird.

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

ALTE POST:

Haben Sie einen Blick auf diesem Thread und speziell auf # 9, sollte https://code.google.com/p/gmaps-api-issues/issues/detail?id=4961

+0

Während dieser Link die Frage beantworten kann, ist es besser, die wesentlichen Teile der Antwort [hier] (http: //meta.stackexchange. com/a/8259) und geben Sie den Link als Referenz an. Nur-Link-Antworten können ungültig werden, wenn sich die verknüpfte Seite ändert. – bummi

2

Ich habe eine UView hilfreich sein, und ich bin das Hinzufügen eines Delegaten zu dem Ansicht, so dass ein UIButton einen Selektor aufruft. Für die Google-Karte, mache ich nichts, wenn ich

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

Allerdings nennen, habe ich meine Infofenster (meine benutzerdefinierte Ansicht) Delegaten selbst, und rufen alle meine Handlungen, wenn ich die Taste drücken, die die verknüpft ist Wähler.

+2

Hallo, wird die Tastenaktion dann für einen Tipp irgendwo in der benutzerdefinierten InfoWindow oder nur eine UI-Taste in ihm ausgelöst? Wenn nur die UIButton, dann könnten Sie bitte den Code einfügen. – vkinra

-1

1) Erstellen Sie eine Unteransicht, die Sie in infoWindow anzeigen möchten.

2) Rahmen der Unteransicht gleich dem Rahmen der InfoWindow-Ansicht setzen.

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

Schnelle 3.0 Lösung

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

und Austritt dieser Ansicht (customInfoWindow) in demselben Controller machen, die mapView hat.

Ich habe die Idee von diesem Link dank diesen Entwickler Custom and interactive googlemaps(IOS SDK) infowindow

Verwandte Themen