Check whether zoom level changed Check whether zoom level changed objective-c objective-c

Check whether zoom level changed


It is pretty simple to calculate the zoom level. See the snippet below. You can get the mRect parameter from the visibleMapRect property on your MKMapView instance.

+ (NSUInteger)zoomLevelForMapRect:(MKMapRect)mRect withMapViewSizeInPixels:(CGSize)viewSizeInPixels{    NSUInteger zoomLevel = MAXIMUM_ZOOM; // MAXIMUM_ZOOM is 20 with MapKit    MKZoomScale zoomScale = mRect.size.width / viewSizeInPixels.width; //MKZoomScale is just a CGFloat typedef    double zoomExponent = log2(zoomScale);    zoomLevel = (NSUInteger)(MAXIMUM_ZOOM - ceil(zoomExponent));    return zoomLevel;}

You could probably just stop at the step for calculating the zoomScale as that will tell you if the zoom has changed at all.

I figured this stuff out from reading Troy Brants excellent blog posts on the topic:

http://troybrant.net/blog/2010/01/mkmapview-and-zoom-levels-a-visual-guide/

Swift 3

extension MKMapView {    var zoomLevel: Int {        let maxZoom: Double = 20        let zoomScale = self.visibleMapRect.size.width / Double(self.frame.size.width)        let zoomExponent = log2(zoomScale)        return Int(maxZoom - ceil(zoomExponent))    }}


I found this very helpful and developed the following code based on these answers.

- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {   mapRegion = self.mapView.region;}-(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{MKCoordinateRegion newRegion = self.mapView.region;NSInteger zFactor;if ((mapRegion.span.latitudeDelta/newRegion.span.latitudeDelta) > 1.5){    NSLog(@"Zoom in changed");    zFactor = 20;    CustomPlacemark *aO;     MKAnnotationView *aV;     for (aO in self.mapView.annotations) {        aV = [[self mapView] viewForAnnotation:aO];        aV.frame = CGRectMake(aV.frame.origin.x, aV.frame.origin.y, aV.frame.size.width+zFactor, aV.frame.size.height+zFactor);        [[[self mapView] viewForAnnotation:aO] setFrame:aV.frame];    }}if ((mapRegion.span.latitudeDelta/newRegion.span.latitudeDelta) < 0.75){    NSLog(@"Zoom out");    zFactor = -20;    CustomPlacemark *aO;     MKAnnotationView *aV;     for (aO in self.mapView.annotations) {        aV = [[self mapView] viewForAnnotation:aO];        aV.frame = CGRectMake(aV.frame.origin.x, aV.frame.origin.y, aV.frame.size.width+zFactor, aV.frame.size.height+zFactor);        [[[self mapView] viewForAnnotation:aO] setFrame:aV.frame];    }  }}


I have the following MKMapView category in which I include a method for quickly getting the current zoom level for the map:

@implementation MKMapView (ZoomLevel)- (NSUInteger) zoomLevel {    MKCoordinateRegion region = self.region;    double centerPixelX = [MKMapView longitudeToPixelSpaceX: region.center.longitude];    double topLeftPixelX = [MKMapView longitudeToPixelSpaceX: region.center.longitude - region.span.longitudeDelta / 2];    double scaledMapWidth = (centerPixelX - topLeftPixelX) * 2;    CGSize mapSizeInPixels = self.bounds.size;    double zoomScale = scaledMapWidth / mapSizeInPixels.width;    double zoomExponent = log(zoomScale) / log(2);    double zoomLevel = 21 - zoomExponent;    return zoomLevel;}@end

To obtain the zoom level, you can call the following in your delegates and determine if the zoom level has changed:

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {    NSUInteger zoomLevel = [mapView zoomLevel];}