我试图在iOS7应用程序中创建MKMapView的快照,就像以前的iOS版本在所有地方都建议使用的方法一样:

- (UIImage*) renderMapViewToImage
{
   UIGraphicsBeginImageContextWithOptions(mapView.frame.size, NO, 0.0);
   [mapView.layer renderInContext:UIGraphicsGetCurrentContext()];
   UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
   UIGraphicsEndImageContext();
   return image;
}

但是,返回的图像是一个黑色矩形,其顶部有一个蓝色当前位置点。
我也尝试过使用mapView的不同子层,但是结果始终是相同的。

有谁知道如何在iOS7中拍摄MKMapView快照?

最佳答案

您可以使用MKMapSnapshotter并从生成的image中获取MKMapSnapshot。请参阅WWDC 2013 session 视频Putting Map Kit in Perspective的讨论。

例如:

MKMapSnapshotOptions *options = [[MKMapSnapshotOptions alloc] init];
options.region = self.mapView.region;
options.scale = [UIScreen mainScreen].scale;
options.size = self.mapView.frame.size;

MKMapSnapshotter *snapshotter = [[MKMapSnapshotter alloc] initWithOptions:options];
[snapshotter startWithCompletionHandler:^(MKMapSnapshot *snapshot, NSError *error) {
    UIImage *image = snapshot.image;
    NSData *data = UIImagePNGRepresentation(image);
    [data writeToFile:[self snapshotFilename] atomically:YES];
}];

话虽如此,renderInContext解决方案仍然对我有用。有一些关于仅在iOS7的主队列中执行此操作的说明,但它似乎仍然有效。但是MKMapSnapshotter似乎是适用于iOS7的更合适的解决方案。

如果要在快照中包括一些注释,则必须手动绘制它们(!)。在Putting Map Kit in Perspective视频的末尾对此进行了详细讨论。我不得不说,这是我见过的苹果建议的最不优雅的实现之一。无论如何,在iOS中,它可能看起来像:
MKMapSnapshotOptions *options = [[MKMapSnapshotOptions alloc] init];
options.region = self.mapView.region;
options.scale = [UIScreen mainScreen].scale;
options.size = self.mapView.frame.size;

MKMapSnapshotter *snapshotter = [[MKMapSnapshotter alloc] initWithOptions:options];
[snapshotter startWithQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) completionHandler:^(MKMapSnapshot *snapshot, NSError *error) {

    // get the image associated with the snapshot

    UIImage *image = snapshot.image;

    // Get the size of the final image

    CGRect finalImageRect = CGRectMake(0, 0, image.size.width, image.size.height);

    // Get a standard annotation view pin. Clearly, Apple assumes that we'll only want to draw standard annotation pins!

    MKAnnotationView *pin = [[MKPinAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:@""];
    UIImage *pinImage = pin.image;

    // ok, let's start to create our final image

    UIGraphicsBeginImageContextWithOptions(image.size, YES, image.scale);

    // first, draw the image from the snapshotter

    [image drawAtPoint:CGPointMake(0, 0)];

    // now, let's iterate through the annotations and draw them, too

    for (id<MKAnnotation>annotation in self.mapView.annotations)
    {
        CGPoint point = [snapshot pointForCoordinate:annotation.coordinate];
        if (CGRectContainsPoint(finalImageRect, point)) // this is too conservative, but you get the idea
        {
            CGPoint pinCenterOffset = pin.centerOffset;
            point.x -= pin.bounds.size.width / 2.0;
            point.y -= pin.bounds.size.height / 2.0;
            point.x += pinCenterOffset.x;
            point.y += pinCenterOffset.y;

            [pinImage drawAtPoint:point];
        }
    }

    // grab the final image

    UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    // and save it

    NSData *data = UIImagePNGRepresentation(finalImage);
    [data writeToFile:[self snapshotFilename] atomically:YES];
}];

对于MacOS实现,请参见该视频以获取更多信息,但是该技术基本相同(创建图像的机制略有不同)。

关于ios - iOS7中的MKMapView快照,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18776288/

10-13 08:07