26

I'm using a MKMapView inside an iPhone app. When I click a button the zoom level must increase. This is my first approach:

MKCoordinateRegion zoomIn = mapView.region;
zoomIn.span.latitudeDelta *= 0.5;
[mapView setRegion:zoomIn animated:YES];

However, this code had no effect, since I didn't update the longitudeDelta value. So I added this line:

zoomIn.span.longitudeDelta *= 0.5;

Now it works, but only sometimes. The latitudeDelta and longitudeDelta don't change in the same way, I mean, their values are not proportional. Any idea how to solve this?

luca
  • 36,606
  • 27
  • 86
  • 125
Hectoret
  • 3,553
  • 13
  • 49
  • 56

10 Answers10

30

I have no idea if this is the right way to do it, but I'm using this to zoom in and out.

        case 0: { // Zoom In
        //NSLog(@"Zoom - IN");
        MKCoordinateRegion region;
        //Set Zoom level using Span
        MKCoordinateSpan span;  
        region.center=mapView.region.center;

        span.latitudeDelta=mapView.region.span.latitudeDelta /2.0002;
        span.longitudeDelta=mapView.region.span.longitudeDelta /2.0002;
        region.span=span;
        [mapView setRegion:region animated:TRUE];
    }
        break;

    // Zoom Out 
    case 2: {
        //NSLog(@"Zoom - OUT");
        MKCoordinateRegion region;
        //Set Zoom level using Span
        MKCoordinateSpan span;  
        region.center=mapView.region.center;
        span.latitudeDelta=mapView.region.span.latitudeDelta *2;
        span.longitudeDelta=mapView.region.span.longitudeDelta *2;
        region.span=span;
        [mapView setRegion:region animated:TRUE];
    }
dkardell
  • 329
  • 3
  • 6
  • this works fine ,but when I continually press the zoom out button it give me exception after some level. How can I prevent it ? – Vivek Shah Apr 15 '15 at 14:23
  • Cool. What is the point of dividing by 2.0002 rather than 2? Just curious :) – dustinrwh Dec 04 '15 at 14:55
  • 2
    hee Zoom -Out Code is crashing when i pressed continuously , can you tell me how to fix ?? here is the Crash Log: Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid Region ' – Sanju Feb 19 '16 at 04:49
28

Just cleaning up dkdarel's answer

// delta is the zoom factor
// 2 will zoom out x2
// .5 will zoom in by x2
- (void)zoomMap:(MKMapView*)mapView byDelta:(float) delta {

    MKCoordinateRegion region = mapView.region;
    MKCoordinateSpan span = mapView.region.span;
    span.latitudeDelta*=delta;
    span.longitudeDelta*=delta;
    region.span=span;
    [mapView setRegion:region animated:YES];

}

Swift Code:

func zoomMap(byFactor delta: Double) {
    var region: MKCoordinateRegion = self.mapView.region
    var span: MKCoordinateSpan = mapView.region.span
    span.latitudeDelta *= delta
    span.longitudeDelta *= delta
    region.span = span
    mapView.setRegion(region, animated: true)
}
Alain Stulz
  • 715
  • 6
  • 19
Kevin
  • 1,883
  • 16
  • 23
  • I think this would be a correct swift code func zoomRegion( region: inout MKCoordinateRegion, byFactor delta: Double) { var span: MKCoordinateSpan = region.span span.latitudeDelta *= delta span.longitudeDelta *= delta region.span = span } – Simon Moshenko Jun 29 '17 at 07:48
24

Here is an easier solution:

MKUserLocation *userLocation = mapView.userLocation;
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance (
      userLocation.location.coordinate, 50, 50);
[mapView setRegion:region animated:NO];
Adam Ivancza
  • 2,459
  • 1
  • 25
  • 36
4

mapView.setRegion method has problem when your map is rotated

You can zoom map via mapView.camera.altitude property, but it is not animated:

mapView.camera.altitude *= 1.05

You can create new camera object and set it with animation:

let currentCamera = mapView.camera
let newCamera: MKMapCamera
if #available(iOS 9.0, *) {
    newCamera = MKMapCamera(lookingAtCenter: currentCamera.centerCoordinate, fromDistance: currentCamera.altitude * 2, pitch: currentCamera.pitch, heading: currentCamera.heading)
} else {
    newCamera = MKMapCamera()
    newCamera.centerCoordinate = currentCamera.centerCoordinate
    newCamera.heading = currentCamera.heading
    newCamera.altitude = currentCamera.altitude * 2
    newCamera.pitch = currentCamera.pitch
}

mapView.setCamera(newCamera, animated: true)
Evgeny Karev
  • 605
  • 6
  • 13
2

Here is my way to move map to the annotation point and zoom pretty close to it. You can easily change the zoom in line CGFloat newLatDelta = 0.06f;

- (void)moveMapToAnnotation:(MKPointAnnotation*)annotation
{
    CGFloat fractionLatLon = map.region.span.latitudeDelta / map.region.span.longitudeDelta;
    CGFloat newLatDelta = 0.06f;
    CGFloat newLonDelta = newLatDelta * fractionLatLon;
    MKCoordinateRegion region = MKCoordinateRegionMake(annotation.coordinate, MKCoordinateSpanMake(newLatDelta, newLonDelta));
    [map setRegion:region animated:YES];
}
Denis Z
  • 133
  • 9
2

Just translated dkardel's solution to swift:

@IBAction func zoomOutButtonClicked(sender: UIButton) {
    let span = MKCoordinateSpan(latitudeDelta: mapView.region.span.latitudeDelta*2, longitudeDelta: mapView.region.span.longitudeDelta*2)
    let region = MKCoordinateRegion(center: mapView.region.center, span: span)

    mapView.setRegion(region, animated: true)
}

@IBAction func zoomInButtonClicked(sender: UIButton) {
    let span = MKCoordinateSpan(latitudeDelta: mapView.region.span.latitudeDelta/2, longitudeDelta: mapView.region.span.longitudeDelta/2)
    let region = MKCoordinateRegion(center: mapView.region.center, span: span)

    mapView.setRegion(region, animated: true)
}
Mohamed Said
  • 4,413
  • 6
  • 35
  • 52
2

In Swift 4.2

let location = mapView.userLocation
let region = MKCoordinateRegion(center: location.coordinate, span: MKCoordinateSpan(latitudeDelta: 50, longitudeDelta: 50))
mapView.setRegion(region, animated: true)
onmyway133
  • 45,645
  • 31
  • 257
  • 263
1

I use similar code to yours and it seems to work. What may be happening is that your delta is not changing enough to cause the zoom level to increase from one google zoom level to the next. This would also depend on the initial state of your map, which could explain why it is intermittent - so how do you set the map and zoom level up to begin with, before the user presses the zoom button?

You could also look into the regionThatFits method which will adjust the region you provide (name is from memory as I don't have the apple docs handy).

frankodwyer
  • 13,948
  • 9
  • 50
  • 70
1
- (IBAction)btnZoomInPressed
{
    MKCoordinateRegion region;
    MKCoordinateSpan span;
    region.center.latitude = lati;
    region.center.longitude = longi;
    span.latitudeDelta=viewMapSingleVenue.region.span.latitudeDelta /2.0002;
    span.longitudeDelta=viewMapSingleVenue.region.span.longitudeDelta /2.0002;
    region.span=span;
    [viewMapSingleVenue setRegion:region animated:TRUE];
}

- (IBAction)btnZoomOutPressed
{
    MKCoordinateRegion region;
    MKCoordinateSpan span;
    region.center.latitude = lati;
    region.center.longitude = longi;
    span.latitudeDelta=viewMapSingleVenue.region.span.latitudeDelta *2;
    span.longitudeDelta=viewMapSingleVenue.region.span.longitudeDelta *2;
    if(span.latitudeDelta < 200)
    {
    region.span=span;
    [viewMapSingleVenue setRegion:region animated:TRUE];
    }
}
Venu Gopal Tewari
  • 5,672
  • 42
  • 41
0

To zoom out 5%, multiply the region lat/long deltas by 1.05

let region = MKCoordinateRegion(center: mapView.centerCoordinate, span: MKCoordinateSpan(latitudeDelta: mapView.region.span.latitudeDelta*1.05, longitudeDelta: mapView.region.span.longitudeDelta*1.05))
self.mapView.setRegion(region, animated: true)
Adam Neuwirth
  • 529
  • 5
  • 10