Is there a way to change MKAnnotationView style (like from red label with number to green colored label with number).
I want to change this style according to distance from target. My annotation is moving, with user.
I dont want to use remove / add annotation, because it causes “blinking”.
Can it be done someway?
UPDATE:
I am adding code, how I am doing it right now
MKAnnotationView *av = [mapView viewForAnnotation:an];
if ([data->type isMemberOfClass:[UserAnnotationImage class]])
{
UIImage *img = [UIImage imageNamed: ((UserAnnotationImage *)data->type)->url];
[av setImage:img];
}
else if ([data->type isMemberOfClass:[UserAnnotationLabel class]])
{
UIView * v = [av viewWithTag:0];
v = ((UserAnnotationLabel *)data->type)->lbl;
av.frame = ((UserAnnotationLabel *)data->type)->lbl.frame;
}
else if ([data->type isMemberOfClass:[UserAnnotationView class]])
{
UIView * v = [av viewWithTag:0];
v = ((UserAnnotationView *)data->type)->view;
av.frame = ((UserAnnotationView *)data->type)->view.frame;
}
Sadly, its not working 🙁
Yes, basically you get a reference to the annotation view and update its contents directly.
Another way, if you have a custom annotation view class, is to have the annotation view monitor the changes it is interested in (or have something outside tell it) and update itself.
The first approach is simpler if you are using a plain
MKAnnotationVieworMKPinAnnotationView.Wherever you detect that a change to the view is needed, get a reference to the view by calling the map view’s
viewForAnnotationinstance method. This is not the same as calling theviewForAnnotationdelegate method.Once you have a reference to the view, you can modify as needed and the changes should appear immediately.
An important point is that the logic you use to update the view outside the delegate method and the logic you have in the
viewForAnnotationdelegate method must match. This is because the delegate method may get called later (after you’ve updated the view manually) by the map view and when it does, the code there should take the updated data into account.The best way to do that is to have the annotation view construction code in a common method called both by the delegate method and where you update the view manually.
See change UIImage from MKAnnotation in the MKMapView for an example that updates just the annotation view’s
image.For an example (mostly an idea for an approach) of updating the view using a custom annotation view class, see iPad Mapkit – Change title of "Current Location" which updates the view’s pin color periodically (green, purple, red, green, purple, red, etc).
There are too many unknowns in your code to explain why it doesn’t work. For example:
data? Is it annotation-specific (is it related toan)? What istype? Does it change after the annotation has been added to the map?datastoring entire view objects like aUILabelorUIViewinstead of just the underlying data that you want to show in those views?imageNamedrequires the image to be a resource in the project (not any arbitrary url)0(that’s the default for all views). Start numbering from1.I’ll instead give a more detailed but simple(r) example…
Assume you have an annotation class (the one that implements
MKAnnotation) with these properties (in addition to coordinate, title, and subtitle):To address the “important point” mentioned above (that the
viewForAnnotationdelegate method and the view-update-code should use the same logic), we’ll create a method that is passed an annotation view and configures it as needed based on the annotation’s properties. This method will then be called both by theviewForAnnotationdelegate method and the code that manually updates the view when the annotation’s properties change.In this example, I made it so that the annotation view shows the image if
haveImageisYESotherwise it shows the label. Additionally, the label’s background color is based ondistanceFromTarget:The
viewForAnnotationdelegate method would look like this:Finally, the place where the annotation’s properties change and where you want to update the annotation view, the code would look something like this: