How to move a MKAnnotation without adding/removing it from the map?
Solution 1
In Swift 4.0 and IOS 11.0, I just add dynamic attribute to the coordinate property of child class of MKAnnotation class and it works: All Annotations on MapView update their location if coordinate value of MKAnnotation objects are updated:
class CarAnnotation: NSObject, MKAnnotation {
@objc dynamic var coordinate: CLLocationCoordinate2D
//Add your custom code here
}
Solution 2
I found a pretty simple method. I wanted to update my player's position smoothly without removing and then re-adding the player annotation. This works well for pre-iOS4 apps, and what it does is both move the pin and center the map on the pin's new location:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[player setCoordinate:aLoc.coordinate];
[mapView setCenterCoordinate:aLoc.coordinate animated:NO];
[UIView commitAnimations];
Here's the same thing but using the recommended block feature for iOS4:
[UIView animateWithDuration:0.5 animations:^{
[player setCoordinate:aLoc.coordinate];
[mapView setCenterCoordinate:aLoc.coordinate animated:NO];
}];
Solution 3
It is indeed possible without removing and adding the annotation off-course.
You'll need to observe your MKAnnotation's coordinate and update the MKAnnotationView's position when it changes. Alternatively you can (and this is probably the more elegant way of doing it) derive your own MKAnnotation and MKAnnotationView and make them "movable".
See Moving-MKAnnotationView for a detailed example which also animates the position of the annotation.
Solution 4
Subclass MKPointAnnotation and it has the capability to update the annotation view on the map to the new coordinate automatically.
Solution 5
Just use KVO:
[annotation willChangeValueForKey:@"coordinate"];
[annotation didChangeValueForKey:@"coordinate"];
If your MKAnnotation has an setCoordinate method, just include these lines right there:
- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate {
[self willChangeValueForKey:@"coordinate"];
coordinate = newCoordinate;
[self didChangeValueForKey:@"coordinate"];
}
DevDevDev
Updated on March 15, 2020Comments
-
DevDevDev about 4 years
Is it possible to move the coordinate of a MKAnnotation without adding and removing the annotation from the map?
-
DevDevDev about 14 yearsYeah that's the solution I came up with, seems weird to have drawRect determine it's own frame though.
-
Lee Armstrong about 14 yearsAre you able to provide a sample to this at all please?
-
spstanley almost 14 yearsAny method that's updating your pin's position. For me, I have another object sending my map view controller a new position, which I then use to update my player pin's position. But you could receive a new position from an external source, or by the user touching a button or using drag-and-drop, whatever.
-
Stan almost 12 yearsdunno why, but this method makes MapView to redraw itself, so I personally didn't like it.
-
Pradeep Reddy Kypa over 11 years:- I clearly understand what u have mentioned in the above code snippet. I have upvoted your answer. Can you please explain on how to stop the animation at particular map points for a certain 2 seconds and then start moving the object again?
-
Stan over 11 yearsAbout pause: I can't provide you the code but I guess you could use [NSTimer scheduledTimerWithTimeInterval: target: selector: userInfo: repeats:] for pause between map points. That also will give user a chance to use GUI while animation is paused.
-
Pradeep Reddy Kypa over 11 years:- The above approach might work if we need to stop the animation after certain time interval. But here we need to stop the animation based on the coordinate value and then resume after certain seconds. We can use the timer in this case to resume the animation but how to stop the animation based on the coordiinate value?
-
Stan over 11 years
-
delany over 11 yearsThis seems to work. I'm just moving the annotation, not resetting the center - but I don't get any MapView redraws. One issue I do get (which is also an issue with the other, more complex, solutions here) is that the annotation vanishes if you zoom during the animation phase. It reappears at the end of the animation, so it's not a huge deal.
-
jfisk over 11 yearsthe OP is asking for this, and for many users its ncier to see a smooth transition
-
malhal about 10 yearsIt is possible, see my answer above.
-
malhal about 10 yearsOr if you extend MKPointAnnotation then it already has a coordinate property that supports KVO and automatically moves on the map.
-
Afzaal Ahmad almost 7 yearsThanks its work smoothly. just update coordinate of annotation.
-
Ric Santos over 6 yearsIn Swift, be sure to use
dynamic var coordinate
or else KVO will not be automatic -
Samah almost 6 yearsShould be the accepted answer. I never knew about this! You just saved me a bunch of time. ;)
-
Lawris about 5 yearsThis actually does not work, if I remove and add the annotation it works. But simply modifying the coordinates properties and using
mapView.addAnnotation(myAnnotation)
doesn't move the annotation, but if I print the coordinates, they effectively change. I wonder why. -
Ivan Le Hjelmeland almost 5 yearsThis is golden <3