MKMapSnapshotOptions : Adding snapshot of Custom Pin Annotation View or UIView
Asked Answered
D

1

7

I am trying to get snapshot of map view with startWithCompletionHandler methods of MKMapSnapshotter. and I want to add Custom Pin Annotation View to snap shot. and there is a label in my custom annotation view. so I can not show that label when ı am getting snapshot. here is the code:

 let snapshotter = MKMapSnapshotter(options: options)
    snapshotter.startWithCompletionHandler() {
        snapshot, error in

        if error != nil {
            completion(image: nil, error: error)
            return
        }

        let image = snapshot.image
        let pin = MKPinAnnotationView(annotation: nil, reuseIdentifier: "") // I want to use custom annotation view instead of  MKPinAnnotationView
        let pinImage = UIImage(named: "pinImage")

        UIGraphicsBeginImageContextWithOptions(image.size, true, image.scale);
        image.drawAtPoint(CGPointMake(0, 0))
        var homePoint = snapshot.pointForCoordinate(coordinates[0])
        pinImage!.drawAtPoint(homePoint)

        pinImage!.drawAtPoint(snapshot.pointForCoordinate(coordinates[1]))

        let finalImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        completion(image: finalImage, error: nil)
    }

as you can see drawAtPoint is function of UIImage. I try to use UIImageView then I add label to imageView as subView but I cannot use drawAtPoint with imageView so my problem is I cannot add label to mapView snapshot.

you can see what I mean at link : https://www.dropbox.com/s/83hnkiqi87uy5ab/map.png?dl=0

Thanks for advice.

Defensible answered 20/8, 2015 at 15:1 Comment(0)
I
12

Create Custom AnnotationView Class.When you create MKMapSnapshotter define MKPointAnnotation with coordinate and title.After that define annotationView from your Custom Class.You can init custom annotationView with MKPointAnnotation. And use drawViewHierarchyInRect method instead of drawAtPoint.

Your code must be like that.

    let snapshotter = MKMapSnapshotter(options: options)
    snapshotter.startWithCompletionHandler() {
        snapshot, error in

        if error != nil {
            completion(image: nil, error: error)
            return
        }

        let image = snapshot.image
        var annotation = MKPointAnnotation()
        annotation.coordinate = coordinates[0]
        annotation.title = "Your Title"

        let annotationView = CustomAnnotationView(annotation: annotation, reuseIdentifier: "annotation")
        let pinImage = annotationView.image

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

        image.drawAtPoint(CGPointMake(0, 0)) //map

//            pinImage!.drawAtPoint(snapshot.pointForCoordinate(coordinates[0]))                        

       annotationView.drawViewHierarchyInRect(CGRectMake(snapshot.pointForCoordinate(coordinates[0]).x, snapshot.pointForCoordinate(coordinates[0]).y, annotationView.frame.size.width, annotationView.frame.size.height), afterScreenUpdates: true)


        let finalImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        completion(image: finalImage, error: nil)
    }
Intervene answered 25/8, 2015 at 14:45 Comment(4)
Thanks.This is exactly what I want.Defensible
Can't you just add an annotation to the map before taking the snapshot? Why take a snapshot, add the image and then take yet another screenshot? Seems like a waste of time doesn't it?Mullein
From Apple: "Snapshotter objects do not capture the visual representations of any overlays or annotations that your app creates. If you want those items to appear in the final snapshot, you must draw them on the resulting snapshot image." AppleEpididymis
Be sure to correct rendered pin position to ensure it's bottom located at exact coordinates position. To do so adjust rect.X and rect.Y in drawViewHierarchyInRect method: rect.X -= rect.Width/2 rect.Y -= rect.HeightLooksee

© 2022 - 2024 — McMap. All rights reserved.