Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I understand you want a pin with a custom callout. </p> <p>We can't create a custom callout, but we can create an annotation with a completely customized view. So the trick is to add a second annotation when the first is selected, and make the 2nd annotation view look like a callout bubble.</p> <p>This is the solution posted by users <a href="https://stackoverflow.com/users/607876/djibouti33">djibouti33</a> and <a href="https://stackoverflow.com/users/740597/jacob-jennings">jacob-jennings</a> in the answer: <a href="https://stackoverflow.com/questions/6392931/">MKAnnotationView - Lock custom annotation view to pin on location updates</a>, which in turn is based in a <a href="http://webcache.googleusercontent.com/search?q=cache:0Yp2vE8AxWkJ:blog.asolutions.com/2010/09/building-custom-map-annotation-callouts-part-1/&amp;hl=en&amp;strip=1" rel="nofollow noreferrer">blog post</a> from Asynchrony Solutions. For explanation purposes, here is some UML from a forked project: <img src="https://i.stack.imgur.com/fplwC.png" alt="Annotation with custom XIB"></p> <p>This is a big hack, but also the cleanest way I've seen to implement custom annotations. </p> <p>Start with a NSObject "Content" class which has a coordinate, the class of the callout view to use (in the UML is AnnotationView, but you can create more and set them here), and a dictionary of random values with the title, photo url, etc. Use this class to initialize a MKAnnotation "Annotation" object.</p> <pre><code>#import &lt;MapKit/MapKit.h&gt; @interface Content : NSObject @property (nonatomic,assign) CLLocationCoordinate2D coordinate; // ... @interface Annotation : NSObject &lt;MKAnnotation, AnnotationProtocol&gt; -(id) initWithContent:(Content*)content; // ... </code></pre> <p>The Annotation implements AnnotationProtocol to announce it wants to handle the creation of its own MKAnnotationView. That is, your MKMapViewDelegate should have code like this:</p> <pre><code>- (MKAnnotationView *)mapView:(MKMapView *)aMapView viewForAnnotation:(id&lt;MKAnnotation&gt;)annotation { // if this is a custom annotation, delegate the implementation of the view if ([annotation conformsToProtocol:@protocol(AnnotationProtocol)]) { return [((NSObject&lt;AnnotationProtocol&gt;*)annotation) annotationViewInMap:mapView]; } else { // else, return a standard annotation view // ... } } </code></pre> <p>The view returned will be of type AnnotationView, which implements AnnotationViewProtocol to announce that it wants to handle selection/deselection. Therefore, in your map view controller, the methods mapView:didSelectAnnotationView: and mapView:didDeselectAnnotationView: should delegate in a similar way to what we saw before.</p> <p>When the annotation is selected, a second annotation (CalloutAnnotation) is added, which follows the same behaviour, but this time the view returned (CalloutView) is initialized from a XIB, and contains Core Graphics code (in BaseCalloutView) to animate and replicate a callout.</p> <p>The initializer of the CalloutView class:</p> <pre><code>- (id)initWithAnnotation:(CalloutAnnotation*)annotation { NSString *identifier = NSStringFromClass([self class]); self = [super initWithAnnotation:annotation reuseIdentifier:identifier]; if (self!=nil){ [[NSBundle mainBundle] loadNibNamed:identifier owner:self options:nil]; // prevent the tap and double tap from reaching views underneath UITapGestureRecognizer *tapGestureRecognizer = ... } return self; } </code></pre> <p>To be able to push another view controller from the callout view I used notifications.</p> <p>The SO answer I linked at the top contains two complete projects implementing this code (class names may differ). I have another project using the UML above at <a href="https://github.com/j4n0/callout" rel="nofollow noreferrer">https://github.com/j4n0/callout</a>.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload