I have the following code:
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)annotation{
annotation.image = [UIImage imageNamed:@"pinIconOn.png"];
}
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)annotation{
annotation.image = [UIImage imageNamed:@"pinIconOff.png"];
}
However, when I select the user location, the pin icon appears. How can I set the select annotation as void for the user location, but enabled for all the other annotations?
In the delegate methods, you can check if the selected annotation is of type MKUserLocation
and, if it is, do not change the image.
MKUserLocation
is the documented class of the user location annotation.
In these delegate methods, the second parameter is the MKAnnotationView
.
That class has the property annotation
which points to the underlying annotation model object that the view is for. Check the type of the annotation
property.
For example:
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)annotation{
if ([annotation.annotation isKindOfClass:[MKUserLocation class]])
{
//it's the user location, do nothing
return;
}
annotation.image = [UIImage imageNamed:@"pinIconOn.png"];
}
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)annotation{
if ([annotation.annotation isKindOfClass:[MKUserLocation class]])
{
//it's the user location, do nothing
return;
}
annotation.image = [UIImage imageNamed:@"pinIconOff.png"];
}
Two additional suggestions:
Don't name the parameter annotation
in these delegate methods. Use the same name as suggested in the documentation which is view
because that is what the parameter really is. It is the view object for the annotation -- not the annotation model object itself. This will make the code in the delegate method less confusing.
So change (MKAnnotationView *)annotation
to (MKAnnotationView *)view
and the check becomes if ([view.annotation isKindOfClass:[MKUserLocation class]])
.
Ideally, you should be storing the "selected" state in the annotation model object when these delegate methods are called as well as changing the image on the view. Then, in viewForAnnotation
, the code should check the annotation's state and set the image there using the same logic as the delegate methods (different image based on whether it's "selected" or not) Otherwise, what may happen is that after selecting an annotation, if the user zooms/pans the map, the image may revert back to the value specified in viewForAnnotation
.