iosswiftmapkitmapkitannotationmkcoordinateregion

iOS MapKit - Detect when map is fully zoomed in?


So I am using a clustering library to group annotations and there is a small bug with it whereby some very close together annotations can appear grouped when the map is fully zoomed in. With this being a framework I can't do much about it directly but I can disable all grouping if the map is fully zoomed in. The problem is I can't work out a reliable way of doing this.

Here is my regionDidChangeAnimated code which is ideally where I would like to check if the map is fully zoomed in (to the point where you cant zoom in any more).

func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
    NSOperationQueue().addOperationWithBlock { 
        let scale: Double = Double(self.map.bounds.size.width) / self.map.visibleMapRect.size.width
        let annotations = self.clusteringManager?.clusteredAnnotationsWithinMapRect(self.map.visibleMapRect, withZoomScale: scale)
        self.clusteringManager?.displayAnnotations(annotations, onMapView: self.map)
    }
}

I have tried inspecting the mapView.region.span property but I'm sure this will change depending on screen size etc...

Any suggestions? Thanks in advance.


Solution

  • You need to extend your MKMapView:

    class YourMapView : MKMapView {
    
        // function returns current zoom level of the map
    
        func getCurrentZoom() -> Double {
    
            var angleCamera = self.camera.heading
            if angleCamera > 270 {
                angleCamera = 360 - angleCamera
            } else if angleCamera > 90 {
                angleCamera = fabs(angleCamera - 180)
            }
    
            let angleRad = M_PI * angleCamera / 180 
    
            let width = Double(self.frame.size.width)
            let height = Double(self.frame.size.height)
    
            let offset : Double = 20 // offset of Windows (StatusBar)
            let spanStraight = width * self.region.span.longitudeDelta / (width * cos(angleRad) + (height - offset) * sin(angleRad))
            return log2(360 * ((width / 256) / spanStraight)) + 1;
          }
    
    }
    

    Now your able to read out the current Zoom Level out in the following delegate methods:

    regionDidChangeAnimated
    

    And

    regionWillChangeAnimated