Force MKMapView viewForAnnotation to update

So I have a MKMapView with all my pins added, and the colour of the pin is dependent on whether a value is set for that pin. When I first load the app, viewForAnnotation is called and the colours are set accordingly. However, when I update the pin's details (such as location, title, etc...) I also update the pinColour to find it doesn't update. It looks like viewForAnnotation isn't called again after the initial add.

I have read many questions similar to this and I can confirm that mapView.delegate = self;

Here is my viewForAnnotation code:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(MapAnnotation *)annotation
{
    if([annotation class] == MKUserLocation.class)
        return nil;

    NSString *pinIdentifier = annotation.identifier; // This is a unique string for each pin and is getting populated every time!

    MKPinAnnotationView *annotationView = (MKPinAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier:pinIdentifier];

    if(annotationView == nil)
        annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pinIdentifier];
    else
        annotationView.annotation = annotation; // Never had this line fire...

    annotationView.canShowCallout = YES;
    annotationView.animatesDrop = NO;
    annotationView.enabled = YES;
    annotationView.tag = annotation.counter;

    if(annotation.pinColour == Stopped) // from enum
        annotationView.pinColor = MKPinAnnotationColorRed;
    else
        annotationView.pinColor = MKPinAnnotationColorGreen;

    UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    [infoButton addTarget:self action:@selector(mapCalloutButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
    infoButton.tag = annotation.counter;
    annotationView.rightCalloutAccessoryView = infoButton;

    return annotationView;
}

Here is the code where I add the pin:

CLLocationCoordinate2D annotationCoord;
annotationCoord.latitude = latestPosition.latitude;
annotationCoord.longitude = latestPosition.longitude;

MapAnnotation *annotation = [[MapAnnotation alloc] init];
annotation.coordinate = annotationCoord;
annotation.identifier = theIdentifier;
annotation.title = theTitle;
annotation.subtitle = theSubtitle
annotation.pinColour = [self getPinColour];
annotation.counter = theCounter;

[theMapView addAnnotation:annotation];

Here is the code where I update the pin (different method to add):

updatePin = true;
pinCounter = mapPin.counter;

CLLocationCoordinate2D annotationCoord;
annotationCoord.latitude = latestPosition.latitude;
annotationCoord.longitude = latestPosition.longitude;
[mapPin setCoordinate:annotationCoord];

mapPin.identifier = theIdentifier;
mapPin.subtitle = theSubtitle;
mapPin.pinColour = [self getPinColour];

I'm not sure what I'm missing. viewForAnnotation is obviously working, it's just not ever called after the initial add! If it were to call this function I'm 100% sure it would work as it does the colour change if I restart the app!

EDIT: Oh and I really don't want to start removing annotations and re-adding them. It's what I'm doing in the short term anyway!


Due to the way the map view caches its annotations, you NEED to remove and re-add the annotation if you need to make changes to its appearance. A simple remove & add is the way to go. There is no cache invalidating mechanism but this.

ios - Force MKMapView viewForAnnotation to update, Due to the way the map view caches its annotations, you NEED to remove and re​-add the annotation if you need to make changes to its  The annotation view or nil if the view has not yet been created. This method may also return nil if the annotation is not in the visible map region and therefore does not have an associated annotation view.


Actually, I dont' know if this worked for you but this is how I did it.

I didn't need to delete the annotation from map. All I need to do is tell the map to give me the annotation view for a parameter annotation. The map will return the correct annotation. From there, I have a property for my custom annotation to identify whether it is an active item, if yes, show the normal pin image, else show full pin image.

-(void)updateAnnotationImage:(CustomAnnotation *)paramAnnotation
{
    MKAnnotationView *av = [geoMap viewForAnnotation:paramAnnotation];

    if (paramAnnotation.active)
    {
        av.image = [UIImage imageNamed:@"PinNormal.png"];
    }
    else
    {
        av.image = [UIImage imageNamed:@"PinFull.png"];
    }
}

Bit late but hopefully it helps others who came across this problem.

Refresh MKAnnotationView on a MKMapView, but it might work: Get a view for annotation using MKMapView - (​MKAnnotationView force update of map view (otherwise annotation views won'​t redraw). The MKMap View class supports the ability to annotate the map with custom information. Because a map may have large numbers of annotations, map views differentiate between the annotation objects used to manage the annotation data and the view objects for presenting that data on the map.


I also found this answer helpful: In which case that mapView:viewForAnnotation: will be called?

Whenever you call addAnnotation method

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id < MKAnnotation >)annotation gets called. 

mapView(_:viewFor:), optional func mapView(_ mapView: MKMapView, viewFor annotation: If one exists, update the returned view to reflect the attributes of the specified annotation​  MKMapView; MKMapViewDelegate. Language: Protocol MKMap View Delegate. Optional methods that you use to receive map-related update messages. SDKs. iOS 3.0+ macOS


Swift 2.1:

I had the same issue, and found a quick solution, trigger this when needed, also sending it to the main thread would be wise:

var annotationsArray = mapView.annotations
mapView.removeAnnotations(mapView.annotations)
mapView.addAnnotations(arrayIncs)
arrayIncs.removeAll()

Getting exec bad access error in mapView - iOS, Force MKMapView viewForAnnotation to update. So I have a MKMapView with all my pins added, and the colour of the pin is dependent on whether a value is  Hi Guys, I have a Google Map customrenderer in my Xamarin.iOS project. Here i'm trying to customize by google maps for Drag and drop feature implementation.


Just spent a couple of hours to get this to work on Xamarin; this is a warning for other Xamarin developers. Make sure you use the ViewForAnnotation method and not the GetViewForAnnotation delegate. I was using the wrong method which returned new annotation views instead of the existing ones... of course it wasn't working!

Map View does not show all annotations at first, But you can change this default setting to see all pins if you want. annotations): func mapView(_ mapView: MKMapView, viewFor annotation:  Without setting any delegates, MKMapView still gets a location if the app is allowed for location updates. It gets its location updates for the blue dot from somewhere else.


iPhone and iPad Apps for Absolute Beginners, To do that, you need to invoke the setRegion method of the Map View, which forces the Map View mapView setRegion:region animated:YES]; Finally, you handle the user's touches to change the map view type. viewForAnnotation creates a delegate method that manages your annotation during zooming and scrolling. Swift + Show Current Location and Update Location in a MKMapView. First of all add & Import CoreLocation and MapKit framework in your class. If you are working with iOS 8 you must include the NSLocationAlwaysUsageDescription key in info.plist file of your current project to get the location services to work. import UIKit. import CoreLocation.


Working with MapKit: Annotations and Shape Rendering, MapKit will automatically update this location as the user moves around. mapkit-​user-location. If you use the simulator to test the app, you can  Displaying Custom Pins on MKMapView for iOS. Update: Please note this post is not up to date and today I no longer recommend this approach for customizing pins for iOS Maps. Apple now makes it much easier to customize map pins, please read this.


How to search for location and display results using Apple's MapKit, Apple provides a powerful native map API called MapKit. and leaves it up to the developer to figure out when to stop location updates. func mapView(​mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) Just off the top of my head, you might need to force the tableview datasource to  I want to update map view every 60 seconds & make an annotation with custom pin/image but want to show standard pin [red color - See Figure 6-1] icon to the previously drawn annotation. I tried like below code but that does not working properly.