Search code examples
iosuiviewmkmapviewmapkit

Converting a view from MKMapKit to a region


I am displaying an MKMapView with another custom view overlaid on top (the 'radar' seen below). The radar is simply a static view that always stays centered and doesn't resize - it's not a map annotation. The idea is that a user can scroll and zoom the map until the radar covers a region they are interested in.

enter image description here

What's the best way to get the MKCoordinateRegion covered by the radar? I've tried convert:toRegionFromView: but I'm not seeing the results I would expect:

print("map region: \(mainView.map.region)") 
// region: MKCoordinateRegion(center: __C.CLLocationCoordinate2D(latitude: 37.132839999999987, longitude: -95.785579999999968), span: __C.MKCoordinateSpan(latitudeDelta: 74.933954323122975, longitudeDelta: 61.276015749875469))

let radarRegion = mainView.map.convert(mainView.radar.frame, toRegionFrom: mainView.map)
print("radar region: \(radarRegion)")
// radar region: MKCoordinateRegion(center: __C.CLLocationCoordinate2D(latitude: 32.559875544717606, longitude: -95.760911716686806), span: __C.MKCoordinateSpan(latitudeDelta: 21.752004541359227, longitudeDelta: 25.901697478812096))

I would expect the radarRegion to have the same center coordinate, and a span roughly half, of those of map.region. Neither are true.

Here's a small project that replicates my setup.


Solution

  • According to the Apple documentation, convert:toRegionFrom: method:

    Converts a rectangle in the specified view’s coordinate system to a map region.

    Parameters

    rect The rectangle you want to convert.

    view The view that serves as the reference coordinate system for the rect parameter.

    So you really need to specify the view for which you provide the coordinates as the second parameter, not the map view :)

    So, I believe if you pass in the frame for the radar as the first parameter, you should pass the radar view's parent as the second parameter and that should (theoretically) work.

    Basically, if view is the parent view of which map (the MKMapView instance) and radar (the radar view) are children, I tried the following code:

    let frame = radar.frame
    let radarRegion = map.convert(frame, toRegionFrom:view)
    map.setRegion(radarRegion, animated:true)
    

    Before the above code was executed, this is what the screen looked like:

    enter image description here

    And after the above code runs:

    enter image description here

    The basic region is correct though there is a little bit of shifting up.

    If this is not what you were expecting with regards to the region selected by the radar view, could you please explain what I might be missing?