iOS refresh annotations on mapview
Asked Answered
B

7

12

I have a mapview where the annotation's coordinates are constantly being updated but when I use setCoordinate, the annotation does not move. How do I refresh the annotations to reflect their coordinates?

- (void)updateUnits {

    PFQuery *query = [PFQuery queryWithClassName:@"devices"];
    [query whereKeyExists:@"location"];
    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {

        if (!error) {

            for (PFObject *row in objects) {

                PFGeoPoint *geoPoint = [row objectForKey:@"location"];
                CLLocationCoordinate2D coord = { geoPoint.latitude, geoPoint.longitude };

                for (id<MKAnnotation> ann in mapView.annotations) {

                    if ([ann.title isEqualToString:[row objectForKey:@"deviceid"]]) {

                        [ann setCoordinate:coord];

                        NSLog(@"latitude is: %f" , coord.latitude);
                        NSLog(@"Is called");
                        break;
                    }
                    else {

                        //[self.mapView removeAnnotation:ann];
                    }
                }
            }
        }
        else {

        }
    }];
}
Bosk answered 3/1, 2013 at 0:21 Comment(2)
This can be done by just changing the coordinates in the Annotation object. It does not require the annotation to be removed, and then added to map for the change to come into effectKannry
@NakulSudhakar but its not changing?Richelieu
M
18

Updated (to reflect the solution):

Having your own custom annotations and implementing setCoordinate and/or synthesizing coordinate may cause issues.

Source: http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/LocationAwarenessPG/AnnotatingMaps/AnnotatingMaps.html

Previous solution:

You can simply remove all of the annotations and then re-add them.

[mapView removeAnnotations:[mapView.annotations]];

[mapView addAnnotations:(NSArray *)];

or remove them and re-add them one by one:

for (id<MKAnnotation> annotation in mapView.annotations)
{
    [mapView removeAnnotation:annotation];
    // change coordinates etc
    [mapView addAnnotation:annotation]; 
}
Morrill answered 3/1, 2013 at 2:30 Comment(7)
That is a lot more intensive, when you can just change their coordinates.Bosk
Are they a custom annotation? If so, did you overload the coordinate property?Morrill
Yes it is custom. What do you mean by overload the coordinate property?Bosk
Have you implemented a setCoordinate method or have you put @synthesize coordinate anywhere? It's not likely that you have but that would cause an issue.Morrill
Actually, if you look above, I use id<MKAnnotation> as the class for the ann pointer. So it would not be a custom annotation correct? But when the annotation is first added in another method, it is a custom annotation where I have declared the setCoordinate method and synthesized coordinate.Bosk
I got it to work, I removed my setCoordinate method and it works fine now! Thanks!Bosk
Take note, didDeselectAnnotation will trigger after you remove all annotations.Mcguigan
M
10

Dispatch the add annotation to the main thread rather then attempt to modify the UI on a background thread

dispatch_async(dispatch_get_main_queue()) {
    self.mapView.addAnnotation(annotation)
}
Melancholy answered 11/2, 2016 at 20:42 Comment(1)
Thanks! This helped me with my problem, that the MapView didn't update with my added annotations unless I manually moved the map.Cytochrome
A
9

Swift 3.0 version of Nathan's answer (thank you Nathan):

DispatchQueue.main.async {
    mapView.addAnnotation(annotation)
}

Side note, Nathan's answer should have far more upvotes. I actually needed this help with removing an annotation, the same issue exists and is fixed by dispatching the update to the main queue.

Albertoalberts answered 7/8, 2017 at 22:16 Comment(1)
This is the answer until Apple has a better solution!Graeco
P
0

Try using [self.mapView removeAnnotations:self.mapView.annotations]:

- (void)viewDidAppear:(BOOL)animated
{

[super viewDidAppear:animated];

[self.mapView removeAnnotations:self.mapView.annotations];

PFQuery *query = [PFQuery queryWithClassName:@"caches"];

[query findObjectsInBackgroundWithBlock:^(NSArray *comments, NSError *error)
 {
     for (PFObject *comment in comments)
     {
         NSString *tit = comment[@"titulo"];
         NSString *lat = comment[@"latitud"];
         NSString *lon = comment[@"longitud"];

         float latFloat = [lat floatValue];
         float lonFloat = [lon floatValue];

         CLLocationCoordinate2D Pin;
         Pin.latitude = latFloat;
         Pin.longitude = lonFloat;
         MKPointAnnotation *annotationPoint = [[MKPointAnnotation alloc]init];
         annotationPoint.coordinate = Pin;
         annotationPoint.title = tit;

         [self.mapView addAnnotation:annotationPoint];

     }

 }];
}
Peebles answered 12/2, 2014 at 22:2 Comment(0)
K
0

For dark mode purposes I needed to refresh the views of annotations. I had to call also the delegate method to recreate the view of the annotations.

- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
    [super traitCollectionDidChange:previousTraitCollection];
    if (@available(iOS 13.0, *)) {
        if ([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]) {
            for (id<MKAnnotation> annotation in self.mapView.annotations) {
                [self.mapView removeAnnotation:annotation];
                [self.mapView addAnnotation:annotation];
                [self mapView:self.mapView viewForAnnotation:annotation];
            }
        }
    }
}
Killam answered 22/10, 2019 at 11:22 Comment(0)
T
0

Removing all existing annotations, and re-adding the new or updated annotation list will refresh the mapView. Firstly I tried:

mapView.annotations.removeAll()

but received the error:

"Value of type '(MKMapRect) -> Set<AnyHashable>' has no member 'removeAll'"

However this worked:

for annotation in mapView.annotations{
    mapView.removeAnnotation(annotation)
}
// .. code to add the new or updated annotation list
Tess answered 23/12, 2019 at 20:41 Comment(0)
K
-1

Just Add

mapView.reloadStyle(self)
Kristopherkristos answered 11/6, 2019 at 6:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.