Positioning MKMapView to show multiple annotations at once

The link posted by Jim is now dead, but i was able to find the code (which I had bookmarked somewhere). Hope this helps.

- (void)zoomToFitMapAnnotations:(MKMapView *)mapView { 
    if ([mapView.annotations count] == 0) return; 

    CLLocationCoordinate2D topLeftCoord; 
    topLeftCoord.latitude = -90; 
    topLeftCoord.longitude = 180; 

    CLLocationCoordinate2D bottomRightCoord; 
    bottomRightCoord.latitude = 90; 
    bottomRightCoord.longitude = -180; 

    for(id<MKAnnotation> annotation in mapView.annotations) { 
        topLeftCoord.longitude = fmin(topLeftCoord.longitude, annotation.coordinate.longitude); 
        topLeftCoord.latitude = fmax(topLeftCoord.latitude, annotation.coordinate.latitude); 
        bottomRightCoord.longitude = fmax(bottomRightCoord.longitude, annotation.coordinate.longitude); 
        bottomRightCoord.latitude = fmin(bottomRightCoord.latitude, annotation.coordinate.latitude); 
    } 

    MKCoordinateRegion region; 
    region.center.latitude = topLeftCoord.latitude - (topLeftCoord.latitude - bottomRightCoord.latitude) * 0.5; 
    region.center.longitude = topLeftCoord.longitude + (bottomRightCoord.longitude - topLeftCoord.longitude) * 0.5;      

    // Add a little extra space on the sides
    region.span.latitudeDelta = fabs(topLeftCoord.latitude - bottomRightCoord.latitude) * 1.1;
    region.span.longitudeDelta = fabs(bottomRightCoord.longitude - topLeftCoord.longitude) * 1.1; 

    region = [mapView regionThatFits:region]; 
    [mapView setRegion:region animated:YES]; 
}

I have done something similiar to this to zoom out (or in) to an area that included a point annotation and the current location. You could expand this by looping through your annotations.

The basic steps are:

  • Calculate the min lat/long
  • Calculate the max lat/long
  • Create CLLocation objects for these two points
  • Calculate distance between points
  • Create region using center point between points and distance converted to degrees
  • Pass region into MapView to adjust
  • Use adjusted region to set MapView region
    -(IBAction)zoomOut:(id)sender {

        CLLocationCoordinate2D southWest = _newLocation.coordinate;
        CLLocationCoordinate2D northEast = southWest;

        southWest.latitude = MIN(southWest.latitude, _annotation.coordinate.latitude);
        southWest.longitude = MIN(southWest.longitude, _annotation.coordinate.longitude);

        northEast.latitude = MAX(northEast.latitude, _annotation.coordinate.latitude);
        northEast.longitude = MAX(northEast.longitude, _annotation.coordinate.longitude);

        CLLocation *locSouthWest = [[CLLocation alloc] initWithLatitude:southWest.latitude longitude:southWest.longitude];
        CLLocation *locNorthEast = [[CLLocation alloc] initWithLatitude:northEast.latitude longitude:northEast.longitude];

        // This is a diag distance (if you wanted tighter you could do NE-NW or NE-SE)
        CLLocationDistance meters = [locSouthWest getDistanceFrom:locNorthEast];

        MKCoordinateRegion region;
        region.center.latitude = (southWest.latitude + northEast.latitude) / 2.0;
        region.center.longitude = (southWest.longitude + northEast.longitude) / 2.0;
        region.span.latitudeDelta = meters / 111319.5;
        region.span.longitudeDelta = 0.0;

        _savedRegion = [_mapView regionThatFits:region];
        [_mapView setRegion:_savedRegion animated:YES];

        [locSouthWest release];
        [locNorthEast release];
    }

As of iOS7 you can use showAnnotations:animated:

[mapView showAnnotations:annotations animated:YES];

Why so complicated?

MKCoordinateRegion coordinateRegionForCoordinates(CLLocationCoordinate2D *coords, NSUInteger coordCount) {
    MKMapRect r = MKMapRectNull;
    for (NSUInteger i=0; i < coordCount; ++i) {
        MKMapPoint p = MKMapPointForCoordinate(coords[i]);
        r = MKMapRectUnion(r, MKMapRectMake(p.x, p.y, 0, 0));
    }
    return MKCoordinateRegionForMapRect(r);
}