Changing MKMapView's height AND centerCoordinate with animation causes annotations to flicker

| | August 11, 2015

I have a legacy code to maintain where I have a UIView and inside that container I have an MKMapView. There are custom annotations on this mapView. If I tap on them, the mapContainer and the mapView resizes their height, also the centerCoordinate of the mapView is set to the coordinate of the selected annotation.

@property(nonatomic,weak) IBOutlet UIView *mapContainer;
@property(nonatomic,weak) MKMapView *mapView;

To makes things more complicated these 3 things should happen at the same time animating together. The animation itself is working neatly, so the calculation of the bounds, center, etc should be fine.

@weakify(self);
[UIView animateWithDuration:self.detailsPanelSlideAnimationDuration animations:^ {
    @strongify(self);

    self.mapContainer.bounds = self.mapContainerViewWithDetailsFrame;
    CGPoint center = CGPointMake(CGRectGetWidth(self.mapContainerViewWithDetailsFrame) / 2.0f, CGRectGetHeight(self.mapContainerViewWithDetailsFrame) / 2.0f);
    self.mapContainer.center = center;

    self.mapView.bounds = self.mapViewWithDetailsFrame;
    self.mapView.center = self.mapContainer.center;

    [self.mapView setCenterCoordinate:self.selectedAnnotation.coordinate animated:NO];

    // setting other frames/bounds/centers not related to the map or annotations
    ...

} completion:NULL];

The problem is that during this animation the custom annotation images are not on the correct position. They are going to another direction. They jump into the right place after the animation has completed but this causes an unpleasant experience.

I would remove them before the animation and put them back after but they should be visible during the animation too. What do you suggest I should do?

EDIT:
I thought that forcing the annotations to redraw more frequently during the animation would help this problem, but I had no luck.
(I created a nested animation with repetition. Inside the animation block I iterated through the mapView’s annotations and called setNeedsLayout.)

Leave a Reply