Subclasses of MKAnnotationView
Asked Answered
M

2

6

I was wondering if anyone knows of any subclasses for the MKAnnotationView class. On apples documentation they say one example is the MKPinAnnotationView so I was wondering if there were other pre-created subclasses like the one used to track the devices current location. If anyone has tips for creating my own subclass of the MKAnnotationView class that be great as well.

Thanks, bubster

Minos answered 22/10, 2010 at 5:44 Comment(0)
S
7

I don't know of any other templates, but that does not mean that they don't exist. :)

Anyway, here's how to create custom ones: Create a new class conforming to the MKAnnotation protocol. You will need to have two instance variables of type NSString* named title and subtitle and one of type CLLocationCoordinate2D named coordinate and an appropriate setter method (e.g. property). Those strings are going to be displayed in the callout. In the delegate of your mapView, implement the method -mapView:viewForAnnotation: in a similar way as you would implement the datasource for a UITableView. That is, dequeueing an annotationView by an identifier, setting the new properties (e.g. a button of type UIButtonTypeDetailDisclosure for the right accessory view). You will want to add an image to display underneath the offset. Just use the image property of your MKAnnotationView. The center of your custom image will be placed at the coordinate specified, so you may want to give an offset: aView.centerOffset = CGPointMake(0, -20)

Here is some sample code:

- (MKAnnotationView *) mapView: (MKMapView *) mapView viewForAnnotation: (id<MKAnnotation>) annotation {
    // reuse a view, if one exists
    MKAnnotationView *aView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"pinView"];

    // create a new view else
    if (!aView) {
        aView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"pinView"];
    }

    // now configure the view
    aView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    [(UIButton*)aView.rightCalloutAccessoryView addTarget:self action:@selector(showDetails:) forControlEvents:UIControlEventTouchUpInside];
    aView.canShowCallout = YES;
    aView.enabled = YES;
    aView.image = [UIImage imageNamed:@"green_pin.png"];
    aView.centerOffset = CGPointMake(0, -20);

    return aView;
}
Selenite answered 22/10, 2010 at 8:13 Comment(2)
Thanks for the help. I was also wondering if there is a way to move an annotation after it has been placed on the map?Minos
Just set the coordinate of its annotation to the new value. The mapView uses key-value-observing to be notified of any changes in its annotations and will do the rest for you.Reliable
K
10

In case anyone is still interested in this:

You can get all the subclasses of a class using the Objective-C runtime functions, as described here: http://cocoawithlove.com/2010/01/getting-subclasses-of-objective-c-class.html

Other classes that inherit from MKAnnotationView are:

MKTransitCalloutView, MKAdAnnotationView, MKUserLocationView, MKUserLocationBreadCrumbView, and MKPinAnnotationView

where MKPinAnnotationView is the only one that is documented. All others are private classes that Apple uses internally.

Koweit answered 29/4, 2011 at 1:35 Comment(0)
S
7

I don't know of any other templates, but that does not mean that they don't exist. :)

Anyway, here's how to create custom ones: Create a new class conforming to the MKAnnotation protocol. You will need to have two instance variables of type NSString* named title and subtitle and one of type CLLocationCoordinate2D named coordinate and an appropriate setter method (e.g. property). Those strings are going to be displayed in the callout. In the delegate of your mapView, implement the method -mapView:viewForAnnotation: in a similar way as you would implement the datasource for a UITableView. That is, dequeueing an annotationView by an identifier, setting the new properties (e.g. a button of type UIButtonTypeDetailDisclosure for the right accessory view). You will want to add an image to display underneath the offset. Just use the image property of your MKAnnotationView. The center of your custom image will be placed at the coordinate specified, so you may want to give an offset: aView.centerOffset = CGPointMake(0, -20)

Here is some sample code:

- (MKAnnotationView *) mapView: (MKMapView *) mapView viewForAnnotation: (id<MKAnnotation>) annotation {
    // reuse a view, if one exists
    MKAnnotationView *aView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"pinView"];

    // create a new view else
    if (!aView) {
        aView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"pinView"];
    }

    // now configure the view
    aView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    [(UIButton*)aView.rightCalloutAccessoryView addTarget:self action:@selector(showDetails:) forControlEvents:UIControlEventTouchUpInside];
    aView.canShowCallout = YES;
    aView.enabled = YES;
    aView.image = [UIImage imageNamed:@"green_pin.png"];
    aView.centerOffset = CGPointMake(0, -20);

    return aView;
}
Selenite answered 22/10, 2010 at 8:13 Comment(2)
Thanks for the help. I was also wondering if there is a way to move an annotation after it has been placed on the map?Minos
Just set the coordinate of its annotation to the new value. The mapView uses key-value-observing to be notified of any changes in its annotations and will do the rest for you.Reliable

© 2022 - 2024 — McMap. All rights reserved.