0

It is very easy to animate annotation's coordinate on iOS using the following method:

[UIView animateWithDuration:1.0f
                 animations:^(void){
                     annotation.coordinate = ...
                 }
                 completion:^(BOOL finished)completion{
                     NSLog(@"Animation complete");
                 }

However on OSX equivalent method +[NSAnimationContext runAnimationGroup:] does not work for me - annotation jumps to new location and calls completion handler immediately i.e. it does not last 10 seconds as expected:

[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
    context.duration = 10;

    annotation.coordinate = destination;
} completionHandler:^{
    NSLog(@"Animation complete");
}];

I am new to OSX that's why I guess I'm missing something simple here to make this animation work. One guess I have is that @coordinate property is not animatable on OSX MKMapView's annotations but that would make a really strange difference in implementations of MapKit on iOS and OSX.

I created simple test application to isolate this problem.

Stanislav Pankevich
  • 11,044
  • 8
  • 69
  • 129

2 Answers2

2

Problem solved. I needed to add allowsImplicitAnimation = YES to the code:

[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
    context.duration = 10;
    context.allowsImplicitAnimation = YES;

    annotation.coordinate = destination;
} completionHandler:^{
    NSLog(@"Animation complete");
}];

I found this hint in screenshot from WWDC session in topic: Cocoa: run block after animation on OSX.

Community
  • 1
  • 1
Stanislav Pankevich
  • 11,044
  • 8
  • 69
  • 129
0

Thanks @Stanislav, allowsImplicitAnimation was the missing key for me as well. For reference, here's my Swift 4.1 code for animating an MKMapView with custom duration:

extension MKMapView {
    func animateTo(region: MKCoordinateRegion, duration: TimeInterval) {
        NSAnimationContext.current.allowsImplicitAnimation = true
        NSAnimationContext.current.duration = duration

        NSAnimationContext.runAnimationGroup({ _ in
            self.setRegion(region, animated: true)
        }, completionHandler:{
            print("Animation complete.")
        })
    }
}
Ben Stahl
  • 1,139
  • 11
  • 11