MapView to show all annotations and zoom in as much as possible of the map
Asked Answered
C

4

16

I basically have a map where I add two annotations and they are shown as expected.

Then I´m using the following code:

let annotations = [start, end]
mapView?.showAnnotations(annotations, animated: false)

And this zooms to show my map with the two annotations, but the map could be zoomed in much more and show a more detailed map view.

This is what I get today and this is the expected result that I want.

As you can see the map could be zoomed in a lot more.

Any ideas how to achieve this?

Corpuscle answered 28/9, 2016 at 12:44 Comment(0)
D
25

Use this:

extension MKMapView {
    /// when we call this function, we have already added the annotations to the map, and just want all of them to be displayed.
    func fitAll() {
        var zoomRect            = MKMapRectNull;
        for annotation in annotations {
            let annotationPoint = MKMapPointForCoordinate(annotation.coordinate)
            let pointRect       = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.01, 0.01);
            zoomRect            = MKMapRectUnion(zoomRect, pointRect);
        }
        setVisibleMapRect(zoomRect, edgePadding: UIEdgeInsetsMake(100, 100, 100, 100), animated: true)
    }

    /// we call this function and give it the annotations we want added to the map. we display the annotations if necessary
    func fitAll(in annotations: [MKAnnotation], andShow show: Bool) {
        var zoomRect:MKMapRect  = MKMapRectNull

        for annotation in annotations {
            let aPoint          = MKMapPointForCoordinate(annotation.coordinate)
            let rect            = MKMapRectMake(aPoint.x, aPoint.y, 0.1, 0.1)

            if MKMapRectIsNull(zoomRect) {
                zoomRect = rect
            } else {
                zoomRect = MKMapRectUnion(zoomRect, rect)
            }
        }
        if(show) {
            addAnnotations(annotations)
        }
        setVisibleMapRect(zoomRect, edgePadding: UIEdgeInsets(top: 100, left: 100, bottom: 100, right: 100), animated: true)
    }

}

then, after creating an outlet for your MapView, for example as map, and with you annotations either added to the map of in an array called annotations, access the above methods like so:

map.fitAll()

OR

map.fitAll(in:annotations, true)

respectively.

Use true or false in the last statement depending on whether you had added the annotations to the map before or not...

Dygal answered 7/6, 2017 at 10:55 Comment(0)
M
25

Swift 5.0 / 4.2 version of nyxee's answer

extension MKMapView {

    /// When we call this function, we have already added the annotations to the map, and just want all of them to be displayed.
    func fitAll() {
        var zoomRect            = MKMapRect.null;
        for annotation in annotations {
            let annotationPoint = MKMapPoint(annotation.coordinate)
            let pointRect       = MKMapRect(x: annotationPoint.x, y: annotationPoint.y, width: 0.01, height: 0.01);
            zoomRect            = zoomRect.union(pointRect);
        }
        setVisibleMapRect(zoomRect, edgePadding: UIEdgeInsets(top: 100, left: 100, bottom: 100, right: 100), animated: true)
    }

    /// We call this function and give it the annotations we want added to the map. we display the annotations if necessary
    func fitAll(in annotations: [MKAnnotation], andShow show: Bool) {
        var zoomRect:MKMapRect  = MKMapRect.null
    
        for annotation in annotations {
            let aPoint          = MKMapPoint(annotation.coordinate)
            let rect            = MKMapRect(x: aPoint.x, y: aPoint.y, width: 0.1, height: 0.1)
        
            if zoomRect.isNull {
                zoomRect = rect
            } else {
                zoomRect = zoomRect.union(rect)
            }
        }
        if(show) {
            addAnnotations(annotations)
        }
        setVisibleMapRect(zoomRect, edgePadding: UIEdgeInsets(top: 100, left: 100, bottom: 100, right: 100), animated: true)
    }

}
Mistake answered 27/10, 2018 at 19:49 Comment(1)
it works even though it does not have the green tick.Bonine
M
17

In Swift:

self.mapView.showAnnotations(self.mapView.annotations, animated: true)

This is what I use to show all annotations. almost the same as you are doing yes. the map zoom this to fit the visible or usable section of the map, on my app the zoom is good and does add some padding so that none of the pins are touching the edges.

so possibly once the maps is done you can quickly use setVisibleMapRect:edgePadding:animated: using the new visibleRect with a negative padding.

Mede answered 30/8, 2017 at 20:21 Comment(2)
your solution is much better than extension Mapview solution per my personal request .Gagnon
With the mapView.showAnnotations method it zooms in very well to the group/cluster, but when it's at max zoom it zooms out by default. How to prevent the zoom out affect? And replace with like the callout to show up?Playbill
B
4

Swift 5.3 version with adjustable padding.

extension MKMapView {
    
    func fitAllAnnotations(with padding: UIEdgeInsets = UIEdgeInsets(top: 100, left: 100, bottom: 100, right: 100)) {
        var zoomRect: MKMapRect = .null
        annotations.forEach({
            let annotationPoint = MKMapPoint($0.coordinate)
            let pointRect = MKMapRect(x: annotationPoint.x, y: annotationPoint.y, width: 0.01, height: 0.01)
            zoomRect = zoomRect.union(pointRect)
        })
        
        setVisibleMapRect(zoomRect, edgePadding: padding, animated: true)
    }
    
    func fit(annotations: [MKAnnotation], andShow show: Bool, with padding: UIEdgeInsets = UIEdgeInsets(top: 100, left: 100, bottom: 100, right: 100)) {
        var zoomRect: MKMapRect = .null
        annotations.forEach({
            let aPoint = MKMapPoint($0.coordinate)
            let rect = MKMapRect(x: aPoint.x, y: aPoint.y, width: 0.1, height: 0.1)
            zoomRect = zoomRect.isNull ? rect : zoomRect.union(rect)
        })
        
        if show {
            addAnnotations(annotations)
        }
        
        setVisibleMapRect(zoomRect, edgePadding: padding, animated: true)
    }
}
Buckskins answered 19/5, 2021 at 11:17 Comment(1)
And a SwiftUI version please :-)Omura

© 2022 - 2024 — McMap. All rights reserved.