I am trying to add annotations to a MKMapView
I have created a class CustomMapPin
which conforms to the MKAnnotation
protocol
In viewForAnnotation
, CustomMapAnnotationView
is never actually alloc+inited (the dequeueReusableAnnotationViewWithIdentifier
does not do this).
If viewForAnnotation
is even getting called, it must be returning nil
which means the map view must be putting a red pin somewhere (and if the delegate method isn't getting called, then again the map view will default to a red pin). Log the coordinates where the annotation is being added and look there.
A corrected viewForAnnotation
might look like this:
-(MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
if ([annotation isKindOfClass:[CustomMapPin class]]) {
static NSString *reuseId = @"CustomMapPin";
CustomMapAnnotationView *annotationView = (CustomMapAnnotationView *) [self.mapView dequeueReusableAnnotationViewWithIdentifier:reuseId];
if (!annotationView) {
annotationView = [[CustomMapAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseId];
[annotationView setCanShowCallout:YES];
}
CustomMapPin *customAnnotation = (CustomMapPin *)annotation;
//view's annotation should be set regardless of "type"
[annotationView setAnnotation:customAnnotation];
if ([customAnnotation.type isEqualToString:@"user location"]) {
[annotationView setImage:[UIImage imageNamed:@"pin_user"]];
}
else {
//If it's not a "user location", then set image
//to something else otherwise image will either be nil
//or it will show some other annotation's image...
[annotationView setImage:[UIImage imageNamed:@"pin_other"]];
}
return annotationView;
}
return nil;
}
Some other issues with the code:
viewWillAppear
, code is retrieving the location immediately after calling startUpdatingLocation
. This is not guaranteed to work every time and even if it does "work", you will most likely be getting an old, cached location. When it doesn't work, the annotation will either end up at 0,0 (Atlantic Ocean) or app will crash due to invalid coordinates. It's much better to read the location in the didUpdateLocations
delegate method. In viewWillAppear
, call startUpdatingLocation
and then in didUpdateLocations
, if the accuracy and age of the location is adequate for you, call stopUpdatingLocation
and then use the location (create and add the annotation, etc).CustomMapAnnotationView
, annotationImage
object is created and added but its image
property is never set. The annotationImage
is actually never really used for anything.CustomMapAnnotationView
class is unnecessary for your purpose . In viewForAnnotation
, code is setting the image
property on the CustomMapAnnotationView
(instead of using annotationImage
). This image
property is inherited from MKAnnotationView
. The built-in, basic MKAnnotationView
class is all you need for what you're doing. It already has an image
property and it automatically displays it for you (you don't need to create your own UIImageView
).