Question

This is driving me bonkers!

So, I have custom pins which you can drag around a map which works fine. Because I want them to animate like a standard apple pin (animatesDrop), I use the following event to follow whats going on.

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)annotationView didChangeDragState:(MKAnnotationViewDragState)newState fromOldState:(MKAnnotationViewDragState)oldState

When a user has finished dragging a pin, I need to display a callout saying save/cancel. I fire off the following method, the MKPinAnnotationView (was a UIView) appears but the buttons don't work.

  • I have tried doing it all in code, did not work.
  • I have tried trapping the touch event on the view, did not work.
  • I have made sure the view is retained (selectedPin)
  • I have tried added the view to the superview (saw on a post)
  • I have made sure userInteractionEnabled was on
  • I made the view a controller, I am pretty sure that did not work either

I have had lots of sugar :(

- (void)createYuhuCalloutWithAnnotationView:(MKAnnotationView *)view
{
    MapAnnotation *mapAnnotation = (MapAnnotation *)view.annotation;
    MapYuhuCallout *calloutView = (MapYuhuCallout *)[[[NSBundle mainBundle] loadNibNamed:@"MapYuhuCallout" owner:self options:nil] objectAtIndex:0];

    CGRect calloutViewFrame = calloutView.frame;
    calloutViewFrame.origin = CGPointMake(-calloutViewFrame.size.width/2 + 10, -calloutViewFrame.size.height);
    calloutView.frame = calloutViewFrame;

    [calloutView.saveButton addTarget:self
                           action:@selector(saveYuhuChanges)
                 forControlEvents:UIControlEventTouchUpInside];

    [calloutView.cancelButton addTarget:self
                               action:@selector(cancelYuhuChanges)
                     forControlEvents:UIControlEventTouchUpInside];

    calloutView.leftCalloutAccessoryView = calloutView.saveButton;
    calloutView.rightCalloutAccessoryView = calloutView.cancelButton;

    calloutView.userInteractionEnabled = YES;
    view.userInteractionEnabled = YES;
    [view addSubview:calloutView];

    mapAnnotation.yuhuCalloutView = calloutView;

    self.currentCalloutView = calloutView;
    self.selectedPin = mapAnnotation;
}

UPDATE

I believe I know why this is working but I am not sure how to fix it. I am adding a UIView to a AnnotationView (PIN). The UIView Is a lot bigger than the pin so its frame is bigger. Only the part of the UIView that crosses over the pin is clickable. I expected ClipToBounds to hide the UIView.

So, it seems I need to add a UIView to the actual Map so thats it is clickable or make the AnnotationView (PIN) frame a lot bigger which would cause other issues.

Was it helpful?

Solution

I have a long explanation on custom callout view here https://stackoverflow.com/a/19404994/1226370. In your case best practice would be to add view as subview of your calloutView, and calloutView itself make invisible.

All details about touch handling are described in linked answer.

Hope it will be useful!

OTHER TIPS

Add the following Delegate method which gets called when any UIControl receives a event:

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control {
        NSLog(@"tap event");
    }

If a view is a descendant of the UIControl, map view calls this method as a convenience whenever the user taps your view. You can use this method to respond to taps and perform any actions associated with that control.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top