Should I Use Mkannotation, Mkannotationview or Mkpinannotation

Should I use MKAnnotation, MKAnnotationView or MKPinAnnotation?

I haven't used MonoTouch but the underlying SDK usage is the same as iOS I believe.

MKAnnotation is the protocol/interface to base your annotation data model on. You could also use the pre-defined MKPointAnnotation class (which implements the MKAnnotation interface) for your annotation data model objects instead of creating a custom class if all you need is title, subtitle, and coordinate.

MKAnnotationView is how the annotation's view should appear and is set in the map view's viewForAnnotation delegate method (not created inline). Annotation views can be re-used between multiple annotation objects that will have the same appearance (for example a pin image). So theoretically a single MKAnnotationView instance might be used for multiple annotation objects that implement MKAnnotation (assuming they are not all on the screen at once).

So you create an MKAnnotation-based object and pass that in the addAnnotation (ie. AddAnnotationObject) call. Then in the viewForAnnotation delegate method, you create and return an instance of an MKAnnotationView-based object.

"MKPinAnnotation" (actually MKPinAnnotationView) is a pre-defined subclass of MKAnnotationView which provides a default pin image. You can return an instance of MKPinAnnotationView in the viewForAnnotation delegate method instead of designing a custom view.

The place where you would create the right callout accessory button is in the viewForAnnotation delegate method. You create a UIButton of type UIButtonTypeDetailDisclosure and set it as the annotation view's rightCalloutAccessoryView.

The button press would be handled in the map view's calloutAccessoryControlTapped delegate method which provides a reference to the annotation view and annotation the callout is in.

The method names given are the ones in iOS but the names in MonoTouch should be similar.

MKPinAnnotationView versus MKAnnotationView

The pinView variable is declared as an MKPinAnnotationView but that line creates an MKAnnotationView.

Change this line:

pinView=[[[MKAnnotationView alloc]initWithAnnotation...

to:

pinView=[[[MKPinAnnotationView alloc]initWithAnnotation...


You should also have an else part to that if to handle annotation view re-use:

else
pinView.annotation = annotation;

MKMapView: Instead of Annotation Pin, a custom view

When you want to use your own image for an annotation view, you should create an MKAnnotationView instead of an MKPinAnnotationView.

MKPinAnnotationView is a subclass of MKAnnotationView so it has an image property but it generally overrides that and draws a pin image (that's what it's for).

So change the code to:

-(MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id <MKAnnotation>)annotation 
{
MKAnnotationView *pinView = nil;
if(annotation != mapView.userLocation)
{
static NSString *defaultPinID = @"com.invasivecode.pin";
pinView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( pinView == nil )
pinView = [[MKAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:defaultPinID];

//pinView.pinColor = MKPinAnnotationColorGreen;
pinView.canShowCallout = YES;
//pinView.animatesDrop = YES;
pinView.image = [UIImage imageNamed:@"pinks.jpg"]; //as suggested by Squatch
}
else {
[mapView.userLocation setTitle:@"I am here"];
}
return pinView;
}


Notice that animatesDrop is also commented out since that property only exists in MKPinAnnotationView.

If you still want your image annotations to drop, you'll have to do the animation yourself. You can search Stack Overflow for "animatesdrop mkannotationview" and you'll find several answers. Here are the first two:

  • Is it possible to call animatesDrop in a MKAnnotationView rather than MKPinAnnotationView?
  • How can I create a custom "pin-drop" animation using MKAnnotationView?

Swift - MKPinAnnotation image issue

You want MKAnnotationView, not MKPinAnnotationView. Pin annotations can't customize their image.

See this SO answer for additional details

Stuck on using MKPinAnnotationView() within Swift and MapKit

You need to implement the viewForAnnotation delegate method and return an MKAnnotationView (or subclass) from there.

This is just like in Objective-C -- the underlying SDK works the same way.

Remove the creation of MKPinAnnotationView from the for loop that adds the annotations and implement the delegate method instead.

Here is a sample implementation of the viewForAnnotation delegate method in Swift:

func mapView(mapView: MKMapView!, 
viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {

if annotation is MKUserLocation {
//return nil so map view draws "blue dot" for standard user location
return nil
}

let reuseId = "pin"

var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView
if pinView == nil {
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView!.canShowCallout = true
pinView!.animatesDrop = true
pinView!.pinColor = .Purple
}
else {
pinView!.annotation = annotation
}

return pinView
}


Related Topics



Leave a reply



Submit