-
Create a UIView subclass for the pin callout view.
-
Create a subclass of MKAnnotationView for your map pins.
-
Add an instance of the callout view subclass to your MKAnnotationView subclass.
-
Add a property to toggle the callout view to your MKAnnotationView subclass. This example fades in/out:
- (void)setShowCustomCallout:(BOOL)showCustomCallout { [self setShowCustomCallout:showCustomCallout animated:NO]; } - (void)setShowCustomCallout:(BOOL)showCustomCallout animated:(BOOL)animated { if (_showCustomCallout == showCustomCallout) return; _showCustomCallout = showCustomCallout; void (^animationBlock)(void) = nil; void (^completionBlock)(BOOL finished) = nil; if (_showCustomCallout) { self.calloutView.alpha = 0.0f; animationBlock = ^{ self.calloutView.alpha = 1.0f; [self addSubview:self.calloutView]; }; } else { animationBlock = ^{ self.calloutView.alpha = 0.0f; }; completionBlock = ^(BOOL finished) { [self.calloutView removeFromSuperview]; }; } if (animated) { [UIView animateWithDuration:0.2f animations:animationBlock completion:completionBlock]; } else { animationBlock(); completionBlock(YES); } }
-
Override hitTest:forEvent: to return the callout view if it is currently being shown and the point is within its frame.
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { if (self.showCustomCallout && CGRectContainsPoint(self.calloutView.frame, point)) { return self.calloutView; } else { return nil; } }
-
Subclass MKMapView and override hitTest:forEvent: to avoid callouts hiding when tapped:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { UIView *view = [super hitTest:point withEvent:event]; if ([view isKindOfClass:MyCalloutView.class]) { return nil; // todo: add a new delegate method to the map protocol to handle callout taps } else { return view; } }
-
On your mapview delegate override mapView:didSelectAnnotationView: to show your callout:
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view { if ([view isKindOfClass:MyAnnotationView.class]) { MyAnnotationView *annotationView = (MyAnnotationView *)view; [annotationView setShowCustomCallout:YES animated:YES]; } }
-
On your mapview delegate override mapView:didDeselectAnnotationView: to hide your callout:
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view { if ([view isKindOfClass:[MyAnnotationView class]]) { [((MyAnnotationView *)view) setShowCustomCallout:NO animated:YES]; } }
Last active
May 20, 2018 14:14
-
-
Save ShadoFlameX/7495098 to your computer and use it in GitHub Desktop.
Custom Map Annotation Callouts on iOS
I had implemented your code. but its not working. please help me. My code is in http://stackoverflow.com/questions/32756922/how-to-code-for-mkmapkitview-which-shows-another-container-view-when-user-click link.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Overriding the MKMapView:hitTest:forEvent completely prevents the map from calling "didSelectAnnotationView"...