Reputation:
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?
Here is what I've tried so far (with no success)
// Load the map view
Logs_Map_ViewController *mapViewController = [[Map_ViewController alloc] initWithNibName:@"Map_ViewController" bundle:nil];
mapViewController.GPSCoordinatesToPlot = [someDictionary objectForKey:kGPSCoords];
// Take a picture of the map
UIImage *mapImage = [mapViewController convertMapToImage];
NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(mapImage)];
NSString *base64String = [imageData base64EncodedString];
NOTE: It's really important that the app waits for the map to fully load (so that the image is created properly).
Upvotes: 4
Views: 3089
Reputation: 51
The method below will always be called as the delegate of mapView,
mapViewDidFinishRenderingMap:fullyRendered:
so, you can get map image from mapView here
- (UIImage *)renderToImage:(MKMapView *)mapView
{
UIGraphicsBeginImageContext(mapView.bounds.size);
[mapView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
Upvotes: 0
Reputation:
This may or may not be helpful but this is what I do in my situation.
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.
Upvotes: 1
Reputation: 543
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.
Upvotes: 0