0

I have coordinates of a single pin on my map. I try to center my map on that pin, but I don't want to keep the pin directly in the middle of the map, but in 1/3 of the screen. I tried to do it in the following workaround:

let coordinateRegion = MKCoordinateRegionMakeWithDistance(coordinatesOfThePin, 500, 500)
mapView.setRegion(coordinateRegion, animated: true)

let frame = mapView.frame
let myPoint = CGPointMake(frame.midX, frame.midY/3)
let myCoordinate = mapView.convertPoint(myPoint, toCoordinateFromView: mapView)

let coordinateRegion2 = MKCoordinateRegionMakeWithDistance(myCoordinate, 500, 500)

mapView.setRegion(coordinateRegion2, animated: true)

but it shows random positions depending on the first position of the map. Can you help me with rewriting my code so that I could just put a pin location and get the result as follows:

-------------------
|                 |
|                 |
|        X        | <-- my pin in the 1/3 of the visible map area.
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
-------------------
user3766930
  • 5,629
  • 10
  • 51
  • 104

1 Answers1

5

If you want the point to use the current zoom in scale, but just center on a coordinate such that it's 1/3rd the way up the screen, you could just set the centerCoordinate and then nudge it up one sixth the latitudeDelta of the span:

func updateMapForCoordinate(coordinate: CLLocationCoordinate2D) {
    var center = coordinate;
    center.latitude -= self.mapView.region.span.latitudeDelta / 6.0;
    mapView.setCenterCoordinate(center, animated: true);
}

Tweak the adjustment of the center as you see fit, but hopefully this illustrates one simple approach. Obviously, this little trick only works if the map is has no pitch and isn't rotated.


If you want to zoom in first, you can set the camera, and then reset the centerCoordinate:

func updateMapForCoordinate(coordinate: CLLocationCoordinate2D) {
    let camera = MKMapCamera(lookingAtCenterCoordinate: coordinate, fromDistance: 1000, pitch: 0, heading: 0)
    mapView.setCamera(camera, animated: false)
    var center = coordinate;
    center.latitude -= self.mapView.region.span.latitudeDelta / 6.0;
    mapView.setCenterCoordinate(center, animated: false);
}
Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Ok I did it and it works great, thanks! One more thing here though - is there a way of setting zoom on the map? I attached this code to a button and when user presses it the map centers accordingly on my pin, but I would also like to adjust the zoom to at least street level (e.g. 500) - is that possible? – user3766930 May 18 '16 at 11:32
  • @user3766930 - Then set the camera first, as shown in this revised code sample. – Rob May 18 '16 at 16:08
  • Thanks for the comment @Rob, however I see that `lookingAtCenterCoordinate` is only available from ios 9.0 - is there maybe some other way that could potentially work with older ios? – user3766930 May 18 '16 at 20:21
  • 1
    Then use `cameraLookingAtCenterCoordinate:fromEyeCoordinate:eyeAltitude:`. – Rob May 18 '16 at 20:27
  • Thanks, one last thing - when I used your solution proposed in the edit to the original answer, with both `animated` set to false it works great. But when I change both `animated` to true then the zoom goes to some random place... Do you know why that affects showing the correct position? – user3766930 May 18 '16 at 21:07
  • 1
    That's because the second example uses the camera position immediately after setting to figure out how far to adjust the center, but if animating, the center hasn't finished moving to the final spot yet, so it's probably grabbing wherever the map was, mid animation. That's why I turned off animation. If you wanted to hardcore the ⅙ of the what the desired `latitudeDelta` should be for your final `region` and thereby avoid setting the camera and then tweaking the `centerCoordinate`. you could do that, too. There are many ways to skin the cat. – Rob May 18 '16 at 21:36
  • Rob, thank you very much for clear answer and your patience. I have the very last question related to this topic - is there maybe a way of introducing some kind of completion handler here, so that the `setCenterCoordinate` will wait for `lookingAtCenterCoordinate` to finish working? – user3766930 May 20 '16 at 00:25