I have a situation whereby I need a way of loading an MKMapView with several overlays. This map view shouldn't be shown onscreen, the only reason I require it to load is in order to create an image from the map for use elsewhere.

I have had a look around online but I haven't had any luck with finding a solution to the problem. Please can someone help me out?

3 Answers
3

You should be able to implement mapViewDidFinishLoadingMap in the MKMapViewDelegate protocol and store your image there, I would think. That should solve the problem of needing to wait until the map is loaded to store the image.

If you're seeing other issues as well, please provide more detail on those, as your question is not clear on the specific issue(s) that you're asking about.

I have tried implementing this delegate method, however it never seems to get called since I don't ever display the view containing the mapview.
–
The Crazy ChimpMay 14 '12 at 18:55

Ah, yes. You're right, you're almost certainly not going to be able to get the actual map image without displaying the mapView, because that's what triggers it to go get data. In addition, and I bring this up only because the StackOverflow community will almost certainly innundate you with responses stating such if I don't, that it is probably a violation of Google's terms of service to use the MKMapView data for anything other than actually displaying a map. IANAL, and I'm not connected to Google, just mentioning it. Regardless, the MKMapView isn't really usable as a non-visible data source.
–
strings42May 14 '12 at 22:29

Ahh I see, thank you. I was not aware of this as an issue - I made the assumption that it would be ok to take a snap of the map and email it. Thanks for the clarification.
–
The Crazy ChimpMay 15 '12 at 13:23

You can insert the map view underneath your view controller's view. This way, the map view itself is never seen, but since it's added to the view hierarchy, the delegate methods will fire.
–
jmstoneOct 16 '12 at 5:29

I have a tableview for an venue/business with 7 table cells. One of the table cells contains a map with pindrop. When the user views an establishment for the very first time, i run a quick conditional to see if the mapview has been cached (or rather, saved as image). if the image does not exist, i load a fresh mapview into the cell and add a single pindrop annotation. After both the mapview has loaded and the annotation has dropped, i save the view layer to image, then remove the mapview (and release it since we needed to keep the delegate alive) from the cell and replace with the fresh new image. I suggest spawing a background thread to save the image/insert into cell. This way the table view doesn't choke up.

And then finally, the next time the user returns to that same venue/business, the mapview image exists and i load the image.

I know it's important for the map to fully load, otherwise your image saves with gray where the map did not load. if you're dropping a pin drop, you need to make sure your image saving method fires after both the map finished loading (mapViewDidFinishLoadingMap:) and your annotation has dropped (mapView:didAddAnnotationViews:). Only after both have finished should you fire method to save image. i suggest using a delayed selector. I delay it by 1 second.

This same concept can surely be applied to other situations. Bottom line is, as strings42 states, you're going to have to add a visible mapview to your view in order to capture an image.