Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Failed to set maprect to show all annotations

I have 2 annotations to display on the mapview, but unable to set the maprect to show all of them on screen without requiring users to zoom out.

I tried with showAnnotations but no luck. Anyone has been able to do this in Swift and Xcode 6.1.1?

Here is my code:

class ViewController: UIViewController, MKMapViewDelegate {


    @IBOutlet var map: MKMapView!

    override func viewDidLoad() {
        super.viewDidLoad()

        var mapView = map
        // 1
        let point1 = CLLocationCoordinate2D(latitude: 38.915565, longitude: -77.093524)
        let point2 = CLLocationCoordinate2D(latitude: 38.890693, longitude: -76.933318)

        //2
        let annotation = MKPointAnnotation()
        annotation.setCoordinate(point1)
        annotation.title = "point1"
        map.addAnnotation(annotation)

        let annotation2 = MKPointAnnotation()
        annotation2.setCoordinate(point2)
        annotation2.title = "point2"
        map.addAnnotation(annotation2)

        //3
        // option1: set maprect to cover all annotations, doesn't work
        var points = [annotation, annotation2]
        var rect = MKMapRectNull
        for p in points {
            let k = MKMapPointForCoordinate(p.coordinate)
            rect = MKMapRectUnion(rect, MKMapRectMake(k.x, k.y, 0.1, 0.1))
            println("result: x = \(rect.origin.x) y = \(rect.origin.y)")
        }

        map.setVisibleMapRect(rect, animated: true)

        // option 2: using showAnnotations, doesn't work
        //map.showAnnotations(points, animated: true)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


     }

This is what I got currently: enter image description here

This is what I expected to see: enter image description here

Thanks for your help.

like image 447
tala9999 Avatar asked Jan 26 '15 16:01

tala9999


3 Answers

I finally found out why the pins of the annotations had not been displayed in the visible region of the screen. I think the MapKit framework behaves a bit different than in the previous versions. Since I use autolayout to allow the map to expand to the entire screen for all devices (iPhones, iPad), setVisibleMapRect or mapView.showAnnotations of the map should be invoked in mapViewDidFinishLoadingMap, not in viewDidLoad of the view controller

For example:

 func mapViewDidFinishLoadingMap(_ mapView: MKMapView) {
     // this is where visible maprect should be set
     mapView.showAnnotations(mapView.annotations, animated: true)  
 }
like image 138
tala9999 Avatar answered Oct 17 '22 05:10

tala9999


I had this same problem when I called

viewDidLoad() {
    mapView.showAnnotations(myAnnotations, animated: false)
}

However, moving the call to viewDidLayoutSubviews() also seems to fix the problem (not that isInitialLoad is initialized to true in viewDidLoad).

viewDidLayoutSubviews() {
    if isInitialLoad {
        mapView.showAnnotations(myAnnotations, animated: false)
        isInitialLoad = false
    }
} 

The difference (I think it is an advantage) of putting the call in viewDidLayoutSubviews is that the map hasn't actually displayed yet, so your initial display is that area defined by the annotations. However, it seems that it is called every time the map zooms, so you need to be sure to only call it the first time.

like image 43
Mario Hendricks Avatar answered Oct 17 '22 06:10

Mario Hendricks


For me using showing annotations after map did finish loading did not work.

func mapViewDidFinishLoadingMap(mapView: MKMapView!) {
 // this is where visible maprect should be set
 mapView.showAnnotations(mapView.annotations, animated: true)  
}

Besides showing the annotation, I needed to calculate polylines to connect the annotations and map finished loading was triggered too early.

Instead I tried mapViewDidFinishRenderingMap and it worked perfectly fine. See example below:

//MARK: - Show all objects after adding them on the map
func mapViewDidFinishRenderingMap(mapView: MKMapView, fullyRendered: Bool) {
    mapView.showAnnotations(mapStages, animated: true)
}
like image 2
G. Pejic Avatar answered Oct 17 '22 05:10

G. Pejic