显示图像和标题的MapView批注

时间:2018-08-07 02:03:30

标签: ios swift annotations mkmapview

我正在开发一个应用程序,该应用程序中应显示显示图像和标题的MapView批注。以下View Controller Swift代码在下面显示了默认的图钉图像以及所需的标题:

import UIKit
import MapKit

class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {

    @IBOutlet weak var mapView: MKMapView!

    var locationManager = CLLocationManager()

    override func viewDidLoad() {
        super.viewDidLoad()

        mapView.delegate = self
        locationManager.delegate = self

        // Define zoom
        let deltaLat: CLLocationDegrees = 1.0
        let deltaLon: CLLocationDegrees = 1.0

        // Define location of center coordinates
        let location: CLLocationCoordinate2D = CLLocationCoordinate2DMake(-15.3, -47.0)        

        // Define area to be viwed
        let areaVisual: MKCoordinateSpan = MKCoordinateSpanMake(deltaLat, deltaLon)
        let region = MKCoordinateRegionMake(location, areaVisual)
        let annotation = MKPointAnnotation()   
        annotation.coordinate = location
        annotation.title = "SDKP"
        mapView.addAnnotation(annotation)

        // Show map region defined by the above parameters
        mapView.setRegion(region, animated: true)
    }

    /*
    // Show an image for annotation
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        let annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: nil)
        annotationView.image =  imageLiteral(resourceName: "AnnotationImage")
        return annotationView
    }
    */
}

这是我得到的MapView:

enter image description here

取消注释视图的注释时,会得到所需的注释图像,但没有标题:

enter image description here

关于如何同时获得注释的图像和标题的任何想法?

3 个答案:

答案 0 :(得分:1)

我找到了一种解决方案,其中我在下面的代码中使用功能imageFromLabel(_:)来扩展UIImage,以使用作为标注标题的标签文本创建图像。然后,我通过功能combineImageAndTitle(_:_:)将注释图像与此标题图像结合起来。最后,通过mapView委托方法viewFor annotation显示此组合图像。

由于我仍然是Swift的初学者,因此我不确定这是否是最好的方法。但是这个解决方案对我来说很好用。

import UIKit
import MapKit

class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {

    @IBOutlet weak var mapView: MKMapView!

    var locationManager = CLLocationManager()

    override func viewDidLoad() {
        super.viewDidLoad()

        mapView.delegate = self
        locationManager.delegate = self

        // Define zoom
        let deltaLat: CLLocationDegrees = 1.0
        let deltaLon: CLLocationDegrees = 1.0

        // Define location of center coordinates
        let location: CLLocationCoordinate2D = CLLocationCoordinate2DMake(-15.3, -47.0)

        // Define area to be viwed
        let areaVisual: MKCoordinateSpan = MKCoordinateSpan(latitudeDelta: deltaLat, longitudeDelta: deltaLon)
        let region = MKCoordinateRegion(center: location, span: areaVisual)
        let annotation = MKPointAnnotation()
        annotation.coordinate = location
        annotation.title = "SDKP"
        mapView.addAnnotation(annotation)

        // Show map region defined by the above parameters
        mapView.setRegion(region, animated: true)
    }


    // Delegate method for mapView
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        let annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: nil)
        let imageForAnnotation = #imageLiteral(resourceName: "BaseImage")
        let annotationTitle = (annotation.title ?? "") ?? ""
        //annotationView.image = imageForAnnotation
        annotationView.image = combineImageAndTitle(image: imageForAnnotation, title: annotationTitle)
        return annotationView
    }


    /// Combine image and title in one image.
    func combineImageAndTitle(image: UIImage, title: String) -> UIImage {
        // Create an image from ident text
        let label = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 20))
        label.numberOfLines = 1
        label.textAlignment = .center
        label.textColor = UIColor.black
        label.text = title
        let titleImage = UIImage.imageFromLabel(label: label)

        // Resulting image has a 100 by 100 size
        let contextSize = CGSize(width: 100, height: 100)

        UIGraphicsBeginImageContextWithOptions(contextSize, false, UIScreen.main.scale)

        let rect1 = CGRect(x: 50 - Int(image.size.width / 2), y: 50 - Int(image.size.height / 2), width: Int(image.size.width), height: Int(image.size.height))
        image.draw(in: rect1)

        let rect2 = CGRect(x: 0, y: 53 + Int(image.size.height / 2), width: Int(titleImage.size.width), height: Int(titleImage.size.height))
        titleImage.draw(in: rect2)

        let combinedImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return combinedImage!
    }

}


extension UIImage {
    /// Convert a label to an image
    class func imageFromLabel(label: UILabel) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(label.bounds.size, false, 0.0)
        label.layer.render(in: UIGraphicsGetCurrentContext()!)
        let img = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return img!
    }
}

And this is the resulting MapView.

答案 1 :(得分:0)

class ViewController: UIViewController, MKMapViewDelegate {

    @IBOutlet weak var mapView: MKMapView!

    private func addAnnotation(coordinate coordinate: CLLocationCoordinate2D, title: String, subtitle: String) {
        let annotation = MKPointAnnotation()
        annotation.coordinate = coordinate
        annotation.title = title
        annotation.subtitle = subtitle
        mapView.addAnnotation(annotation)
    }

    func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
        if annotation is MKUserLocation { return nil }

        let identifier = "CustomAnnotation"

        var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier)

        if annotationView == nil {
            annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: identifier)
            annotationView!.canShowCallout = true
            annotationView!.image = UIImage(named: "star.png")!   // go ahead and use forced unwrapping and you'll be notified if it can't be found; alternatively, use `guard` statement to accomplish the same thing and show a custom error message
        } else {
            annotationView!.annotation = annotation
        }

        return annotationView
    }

    ...
}

答案 2 :(得分:0)

您可以使用MKMarkerAnnotationViewglyphImage属性。尝试以下代码

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    let annotationView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: nil)
    annotationView.glyphImage = UIImage(named: "Laugh")
    return annotationView
}