1

I'm trying to segue from a mapView to a page that contains a snapshot of a chosen location on that mapView.

Here is my prepareForSegue method:

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"LocationConfirmSegue"]) {
        LocationConfirmationViewController *vc = segue.destinationViewController;

        MKCoordinateSpan span;
        span.longitudeDelta = mapFocusSpan;
        span.latitudeDelta = mapFocusSpan;

        MKCoordinateRegion region;
        region.center = *currentPinLocation;
        region.span = span;

        MKMapSnapshotOptions *options = [[MKMapSnapshotOptions alloc] init];
        options.region = region;
        options.size = CGSizeMake(270, 180);

        MKMapSnapshotter *snapshotter = [[MKMapSnapshotter alloc] initWithOptions:options];
        [snapshotter startWithCompletionHandler:    ^(MKMapSnapshot * _Nullable snapshot, NSError * _Nullable error) {
            if (error) {
                NSLog(@"%@", error);
                return;
            }

            vc.mapSnapshot = snapshot.image;
        }];
    }
}

I can pass information to the destination VC fine outside of the snapshotter's completion handler. The code all works fine, too––snapshot.image does indeed return a UIImage*––however it's not being passed to the destination view controller. When I try to access the mapSnapshot property in that view controller, I get (null).

Jumhyn
  • 6,687
  • 9
  • 48
  • 76
Philip S
  • 502
  • 6
  • 18
  • One possible solution I can think of would to just pass the "options" to the destination view controller and generate the snapshot there. That feels like a hack, though, and an alternative (where I don't have to import MapKit in the destination view controller) would be greatly appreciated. – Philip S Jan 11 '18 at 03:11
  • 1
    Instead of generating the snapshot in `prepare(for:)`, I would initiate the snapshot where you are presently initiating the segue, and then once the snapshot has been generated, trigger the segue from the completion block of the snapshotter – Paulw11 Jan 11 '18 at 03:16

1 Answers1

0

Take advantage of Apple's OpenGLES screenshot to prevent the inability to get a layer image of the map or a black screen

-(UIImage *)zjcCutScreenImage {
NSInteger myDataLength = self.width * self.height * 4; 
GLubyte *buffer = (GLubyte *) malloc(myDataLength);
glReadPixels(0, 0, self.width, self.height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
GLubyte *buffer2 = (GLubyte *) malloc(myDataLength);
for(int y = 0; y <self.height; y++) {
    for(int x = 0; x <self.width * 4; x++){
        buffer2[(JSNDHC - y) * self.width * 4 + x] = buffer[y * 4 * 1024 + x];
    }
}
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer2, myDataLength, NULL);
int bitsPerComponent = 8;
int bitsPerPixel = 32;
int bytesPerRow = 4 * self.height;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
CGImageRef imageRef = CGImageCreate(self.width, self.height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);
UIImage *myImage = [UIImage imageWithCGImage:imageRef];
return myImage;
}
Tim
  • 1,528
  • 1
  • 11
  • 8