According to the WWDC 'Putting MapKit in Perspective' video you should avoid any approach using completion handlers for animating map cameras in sequence. Rather you should set a delegate on your map view and listen for the regionDidChangeAnimated: call to trigger the next camera in your sequence. This way the speed of the camera movement can be controlled with animateWithDuration:
-(void)flyToLocation:(CLLocationCoordinate2D)toLocation {
CLLocationCoordinate2D startCoord = self.mapView.camera.centerCoordinate;
CLLocationCoordinate2D eye = CLLocationCoordinate2DMake(toLocation.latitude, toLocation.longitude);
MKMapCamera *upCam = [MKMapCamera cameraLookingAtCenterCoordinate:startCoord
fromEyeCoordinate:startCoord
eyeAltitude:80000];
MKMapCamera *turnCam = [MKMapCamera cameraLookingAtCenterCoordinate:toLocation
fromEyeCoordinate:startCoord
eyeAltitude:80000];
MKMapCamera *inCam = [MKMapCamera cameraLookingAtCenterCoordinate:toLocation
fromEyeCoordinate:eye
eyeAltitude:26000];
self.camerasArray = [NSMutableArray arrayWithObjects:upCam, turnCam, inCam, nil];
[self gotoNextCamera];
}
-(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
[self gotoNextCamera];
}
-(void)gotoNextCamera {
if (self.camerasArray.count == 0) {
return;
}
MKMapCamera *nextCam = [self.camerasArray firstObject];
[self.camerasArray removeObjectAtIndex:0];
[UIView animateWithDuration:3.0 animations:^{
self.mapView.camera = nextCam;
}];
}