I had this exact problem, I tried @Jona approach of a delay, but I found that on certain devices it works and others it doesn't. Its all down to the device setup/performance, so using delays isn't really the best solution.
My problem was that I was trying to move/zoom the map (with animation) before opening the callout view (with animation) on the specific pin I wanted to show. Doing this lead to poor performance and the callout being partially off screen.
I decided to use the UIView animateWithDuration
method, this method has its own completion block and thus no delay is needed. Note: when using the UIView animateWithDuration
method, you can set the animated
method to NO
(or false
in Swift). As the UIView
animation block will take care of the animation for us.
-(void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
// Loop through the pins on the
// map and find the added pin.
for (MKAnnotationView *annotationView in views) {
// If the current pin is the
// added pin zoom in on it.
if (annotationView.annotation != mapView.userLocation) {
// Set the map region to be
// close to the added pin.
MKCoordinateSpan span = MKCoordinateSpanMake(0.15, 0.15);
MKCoordinateRegion region = MKCoordinateRegionMake(annotationView.annotation.coordinate, span);
[mapView regionThatFits:region];
// Only perform the annotation popup
// when the animation has been completed.
[UIView animateWithDuration:0.4 delay:0.0 options:(UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionCurveEaseOut) animations:^{
// Set the map region.
[mapView setRegion:region];
} completion:^(BOOL finished) {
// Force open the annotation popup.
[usersMap selectAnnotation:annotationView.annotation animated:YES];
}];
}
}
}