7

I have added Google maps sdk for ios to my Iphone app, and i have some custom markers if clicked info window pops up with title, how can i add a button to this info window so if pressed will go to new page? Now i have tryed to use this post to solve this issue Adding Click Event on InfoWindow/Marker in Google Maps SDK for native iOS/objective C it doesnt give me error but it won't work.

this is what i want my result to be:http://www.flickr.com/photos/74719051@N05/6728157477/

Community
  • 1
  • 1
user1810991
  • 159
  • 2
  • 2
  • 8

4 Answers4

8

The answer for the question you linked shows code for using MapKit, so it wouldn't work with the Google Maps SDK for iOS.

See this question for how to return a custom view with the Google Maps SDK for iOS:

Custom annotation view in Google Maps SDK

However note that according to this question, it looks like what is displayed might be a visual copy of the view not the actual view, which might limit the interaction you can do with the view:

Add buttons to view returned by markerInfoWindow delegate method

Simply detecting a tap on the info window and going to a different page should be possible using didTapWindowOfMarker though.

Note that there's a feature request in Google's issue tracker to add direct support for this:

https://code.google.com/p/gmaps-api-issues/issues/detail?id=4961

Community
  • 1
  • 1
Saxon Druce
  • 17,406
  • 5
  • 50
  • 71
  • 1
    This is what i used: - (void)mapView:(GMSMapView *)mapView didTapInfoWindowOfMarker:(id)marker { [self performSegueWithIdentifier:@"ViewController" sender:[marker snippet]]; } it is not a good solution to replace a button, but it works! THANKS – user1810991 Mar 21 '13 at 16:31
  • User1810991, I tried using your **performSegueWithIdentifier:** solution but I'm getting an error. What exactly does the identifier (the first parameter) need to correspond to? I made it match by containing view controller and that did not work – Charlie J Dec 20 '13 at 21:29
  • Hi Charlie, it's the name of the segue - click the segue (the connecting line on your storyboard) and then set its identifier. – Saxon Druce Dec 20 '13 at 23:49
5

This code does exactly what you want. It's inspired by #9 in the link recommended by Saxon Druce but done differently and more complete. It detects tap on buttons added to my custom infoWindow. I create a custom infoWindow with 2 fake buttons (they could actually be replaced by images because they won't trigger any action anyway) and I add a transparent UIView with 2 real but transparent buttons over the infoWindow. These buttons will trigger the actions.

Finally, I use a few delegate methods or KVC in order to move the overlaid UIView when the infoWindow itself moves.

- (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;
}
Aurelien Porte
  • 2,692
  • 27
  • 32
1

Swift 3.0 solution for button handling on CustomInfoWindow

https://stackoverflow.com/a/40681031/3933302

More more detail visit this blog

Custom and interactive googlemaps(IOS SDK) infowindow

Community
  • 1
  • 1
Sourabh Sharma
  • 8,222
  • 5
  • 68
  • 78
0

1)Create one subview which you want to show in infoWindow. 2)Set frame of subview equals to frame of infoWindow view.

  subView =  [[[NSBundle mainBundle] loadNibNamed:@"viewName" owner:self options:nil] objectAtIndex:0];
  [subView setFrame:infoview.frame];
  [self.mapview addSubview:subView];
Vivek
  • 11,938
  • 19
  • 92
  • 127
Dhananjay Patil
  • 442
  • 3
  • 10