5

Good day everybody!

I'm developing application for iPhone. I have table view and list of locations that I need to display to user. For this purpose I used MKMapView in every table view cell. But when there are a lot of locations this solution becomes very slow. I want to improve UI performance and replace MKMapView with UIImageView. So I need to render map from MKMapView to UIImage in some NON-MAIN thread. I tried to do it like this:

UIGraphicsBeginImageContext(CGSizeMake(64, 64));
CGContextRef context = UIGraphicsGetCurrentContext();
[[mapView layer] renderInContext:context];
thumbnail_image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

But this code renders only yellow background of the map and pin above specified location. There is no map data such streets, houses, etc. What did I do wrong? Thank You for advice.

Daniil Popov
  • 471
  • 4
  • 15

1 Answers1

3

The reason that you aren't getting any map data is that you aren't waiting for the map data to load. Wait until the map view's mapViewDidFinishLoadingMap: delegate method is called, then take the picture. You might have to take the picture after a small delay, one or two seconds, after the delegate method is called, as I have found that sometimes the delegate method is called a bit early as I mention in this question.

- (void)mapViewDidFinishLoadingMap:(MKMapView*)mapView {
    double delayInSeconds = 2.0;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        UIGraphicsBeginImageContext(CGSizeMake(64, 64));
        CGContextRef context = UIGraphicsGetCurrentContext();
        [mapView.layer renderInContext:context];
        thumbnail_image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    });
}

Note: You'll want to make the dimensions of your map view square so that when you render it in a square image it won't be stretched awkwardly.

Community
  • 1
  • 1
eric.mitchell
  • 8,817
  • 12
  • 54
  • 92
  • The problem is that this delegate method never called. I don't know how to force load map. To tell the truth I use Monotouch and maybe it is bug of this platform. – Daniil Popov Dec 06 '12 at 06:24
  • I've carried out an experiment. Described delegate method is called correctly only when MKMapView is added to superview using AddSubview(). – Daniil Popov Dec 06 '12 at 06:33
  • Correct. The map view won't attempt to load image/map tiles until it is actually part of the view hierarchy. – eric.mitchell Dec 06 '12 at 15:18
  • @Rickay You're still on the main thread via `dispatch_get_main_queue` in your answer. – iwasrobbed Apr 30 '13 at 18:00