MapKit Annotations not showing up on map

ios, mapkit, mkannotation, mkannotationview

Solution

In `viewForAnnotation`, the code is creating and returning an `MKAnnotationView` for annotations of type `Data`.

The `MKAnnotationView` class, by default, creates an empty view. That is, its `image` property is `nil` and the view basically contains no content. So, as-is, the annotation views are being created and added but they are invisible.

You can either:

Set the `image` property on the `MKAnnotationView`:

annov.image = [UIImage imageNamed:@"something"];

Or, simpler, create an `MKPinAnnotationView` instead which is a convenient subclass of `MKAnnotationView` that displays a pin image for you:

MKPinAnnotationView *annov = (MKPinAnnotationView *)[mapView dequeue...
if(!annov)
{
    annov = [[MKPinAnnotationView alloc]initWithAnnotation:annotation
                                        reuseIdentifier:reuseId];
    annov.pinColor = MKPinAnnotationColorRed;  //or Green or Purple
}
else
...

Unrelated: You've created a custom annotation class `Data` which is fine but if all you need are the three properties `title`, `subtitle`, and `coordinate`, then you can just use the pre-defined `MKPointAnnotation` class which lets you set all the properties per-instance:

MKPointAnnotation *ann = [[MKPointAnnotation alloc] init];
ann.title = @"The title";
ann.subtitle = @"A subtitle";
ann.coordinate = CLLocationCoordinate2DMake (60.123456, 10.123456);
[self.mapView addAnnotation:ann];

Problem

I'm having trouble getting the MKAnnotationViews show up on the map in MapKit. I'm using iOS 7, and have now searched the forums and the web for many hours, trying different samples and setups. Below I have the most basic setup possible (I think) to make it work. The app contains a single ViewController with a toolbar with a button on top, and the rest is the MapView. The button triggers the method zoomToUser:(UIBarButtonItem*)sender. Right-clicking and checking my outlets and delegates seem to be correct. I have some NSLog-statements being triggered to output some debug info. First the VC: ``` #import "ViewController.h" #import "Data.h" @interface ViewController () <MKMapViewDelegate> @property (weak, nonatomic) IBOutlet MKMapView *mapView; - (IBAction)zoomToUser:(UIBarButtonItem *)sender; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.mapView.showsUserLocation = YES; Data *ann = [[Data alloc] init]; [self.mapView addAnnotation:ann]; } -(void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [self zoomToUser:nil]; } -(IBAction)zoomToUser:(UIBarButtonItem *)sender { MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(self.mapView.userLocation.coordinate, 2000, 2000); NSLog(@"region: %f x %f",self.mapView.userLocation.coordinate.latitude,self.mapView.userLocation.coordinate.longitude); [self.mapView setRegion:region animated:YES ]; NSArray *arr = self.mapView.annotations; for(int i = 0, max = arr.count; i < max; i++) { id<MKAnnotation> annotation = arr[i]; NSLog(@"%d of %d: %@ (%@)",i+1,max,annotation.title, [annotation class]); } } - (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation { NSString *reuseId = @"Test"; if([annotation isKindOfClass:[MKUserLocation class]]) { return nil; } else if( [annotation isKindOfClass:[Data class]]) { MKAnnotationView *annov = [mapView dequeueReusableAnnotationViewWithIdentifier:reuseId]; if(!annov) { annov = [[MKAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:reuseId]; } else { annov.annotation = annotation; } annov.canShowCallout = YES; NSLog(@"Title: %@",annotation.title); return annov; } else { return nil; } } @end ``` And the `Data` class: ``` #import "Data.h" @implementation Data -(NSString *)title { return @"The title"; } -(NSString *)subtitle { return @"A subtitle"; } -(CLLocationCoordinate2D)coordinate { CLLocationCoordinate2D coordinate; coordinate.latitude = 60.123456; coordinate.longitude = 10.123456; return coordinate; } @end ``` The Data.h: ``` #import <Foundation/Foundation.h> #import <MapKit/MapKit.h> @interface Data : NSObject <MKAnnotation> @end ``` And the ViewController.h: ``` #import <UIKit/UIKit.h> #import <MapKit/MapKit.h> @interface ViewController : UIViewController @end ``` As you can see the `viewForAnnotation`-method prints the annotations title in console when it's requested, and each time the map pans the area, it prints. Pressing the BarButton and triggering the `zoomToUser:`-method logs to console that the map indeed has two annotations, the `MKUserLocation` and the one I added. How come my MapView tells me it has the annotation, it asks for the view, it gets the view, but it does not show it?

Original source