Search code examples
iosswiftanimationmapkitmkannotation

Animate MapKit annotation coordinate change in Swift?


When using MapKit in iOS 8 in Swift, how do I make it possible to animate a change in the map position of a custom annotation? I am saying this:

UIView.animateWithDuration(0.25) {
    var loc = ann.coordinate
    loc.latitude = loc.latitude + 0.0005
    loc.longitude = loc.longitude + 0.001
    ann.coordinate = loc
}

...where ann is a custom annotation, MyAnnotation. The annotation is jumping, not animating, to the new coordinate position.

The annoying thing is that the animation works perfectly if I write MyAnnotation in Objective-C. But if I write it in Swift, I don't get the animation any more!

Just FYI, here is my Swift code for MyAnnotation:

class MyAnnotation : NSObject, MKAnnotation {
    var coordinate : CLLocationCoordinate2D
    var title: String!
    var subtitle: String!

    init(location coord:CLLocationCoordinate2D) {
        self.coordinate = coord
        super.init()
    }
}

Solution

  • You almost have it right! Just change this line in your MyAnnotation implementation:

    var coordinate : CLLocationCoordinate2D
    

    to this:

    dynamic var coordinate : CLLocationCoordinate2D
    

    That will fix it.

    Why does this matter? Because annotation animation relies on KVO (key value observing). In Swift, a property is not key value observable unless it is marked as dynamic. (To get a little more technical, that in turn is because KVO observation works by swizzling the implementation of the property setter method - the runtime reaches right into your class and changes that property's setter code. But in Swift, it can't do that unless you explicitly mark the property as dynamic.)