如何在Mapview Swift ios中添加自定义图像到注释?

时间:2016-12-27 08:40:07

标签: ios swift3 mkmapview mkannotation

 var lat:CLLocationDegrees = 40.748708
    var long:CLLocationDegrees = -73.985643
    var latDelta:CLLocationDegrees = 0.01
    var longDelta:CLLocationDegrees = 0.01

    var span:MKCoordinateSpan = MKCoordinateSpanMake(latDelta, longDelta)
    var location:CLLocationCoordinate2D = CLLocationCoordinate2DMake(lat, long)
    var region:MKCoordinateRegion = MKCoordinateRegionMake(location, span)

    mapView.setRegion(region, animated: true)


    var information = MKPointAnnotation()
    information.coordinate = location
    information.title = "Test Title!"
    information.subtitle = "Subtitle"



    mapView.addAnnotation(information)
    super.viewDidLoad()

    // Do any additional setup after loading the view.
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {


    if !(annotation is MKPointAnnotation) {
        return nil
    }

    let reuseId = "test"

    var anView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId)
    if anView == nil {
        anView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
        anView?.image = UIImage(named:"annotation")
        anView?.canShowCallout = true
    }
    else {
        anView?.annotation = annotation
    }

    return anView
}

我需要在Mapview中为注释加载自定义图像。我有一个名为“注释”的图像,我试图在viewfor注释方法中调用它。我怎样才能做到这一点?

5 个答案:

答案 0 :(得分:4)

以下是答案:

斯威夫特4:

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    // Don't want to show a custom image if the annotation is the user's location.
    guard !(annotation is MKUserLocation) else {
        return nil
    }

    // Better to make this class property
    let annotationIdentifier = "AnnotationIdentifier"

    var annotationView: MKAnnotationView?
    if let dequeuedAnnotationView = mapView.dequeueReusableAnnotationView(withIdentifier: annotationIdentifier) {
        annotationView = dequeuedAnnotationView
        annotationView?.annotation = annotation
    }
    else {
        let av = MKAnnotationView(annotation: annotation, reuseIdentifier: annotationIdentifier)
        av.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
        annotationView = av
    }

    if let annotationView = annotationView {
        // Configure your annotation view here
        annotationView.canShowCallout = true
        annotationView.image = UIImage(named: "yourImage")
    }

    return annotationView
}

斯威夫特3:

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    // Don't want to show a custom image if the annotation is the user's location.
    guard !(annotation is MKUserLocation) else {
        return nil
    }

    // Better to make this class property
    let annotationIdentifier = "AnnotationIdentifier"

    var annotationView: MKAnnotationView?
    if let dequeuedAnnotationView = mapView.dequeueReusableAnnotationView(withIdentifier: annotationIdentifier) {
        annotationView = dequeuedAnnotationView
        annotationView?.annotation = annotation
    }
    else {
        annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: annotationIdentifier)
        annotationView?.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
    }

    if let annotationView = annotationView {
        // Configure your annotation view here
        annotationView.canShowCallout = true
        annotationView.image = UIImage(named: "yourImage")
    }

    return annotationView
}

Swift 2.2:

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
    // Don't want to show a custom image if the annotation is the user's location.
    guard !annotation.isKindOfClass(MKUserLocation) else {
        return nil
    }

    let annotationIdentifier = "AnnotationIdentifier"

    var annotationView: MKAnnotationView?
    if let dequeuedAnnotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(annotationIdentifier) {
        annotationView = dequeuedAnnotationView
        annotationView?.annotation = annotation
    }
    else {
        let av = MKAnnotationView(annotation: annotation, reuseIdentifier: annotationIdentifier)
        av.rightCalloutAccessoryView = UIButton(type: .DetailDisclosure)
        annotationView = av
    }

    if let annotationView = annotationView {
        // Configure your annotation view here
        annotationView.canShowCallout = true
        annotationView.image = UIImage(named: "yourImage")
    }

    return annotationView
}

答案 1 :(得分:2)

Swift 4.0

var coordinates: [[Double]]!
var addresses:[String]!

在viewDidload()中添加以下代码以向MapvView添加注释。

    coordinates = [[28.4344,72.5401],[28.85196,72.3944],[28.15376,72.1953]]// Latitude,Longitude
    addresses = ["Address1","Address2","Address3"]
    self.mapView.delegate = self // set MapView delegate to self
    for i in 0...2 {
        let coordinate = coordinates[i]
        let point = CustomAnnotation(coordinate: CLLocationCoordinate2D(latitude: coordinate[0] , longitude: coordinate[1] )) // CustomAnnotation is class and pass the required param
        point.address = addresses[i] // passing only address to pin, you can add multiple properties according to need
        self.mapView.addAnnotation(point)
    }
    let region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 28.856614, longitude: 72.3522219), span: MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1))
    self.mapView.setRegion(region, animated: true)

为我们的自定义注释添加从MKAnnotation继承的名称为CustomAnnotation的新类

import MapKit
class CustomAnnotation: NSObject, MKAnnotation {
    var coordinate: CLLocationCoordinate2D
    var address: String!
    init(coordinate: CLLocationCoordinate2D) {
        self.coordinate = coordinate
    }
}

再添加一个名为AnnotationView的类,该名称继承自MKAnnotationView。我正在显示自定义标注,因此需要覆盖overridefuncpoint()方法以在自定义标注视图中接收触摸。

import MapKit
class AnnotationView: MKAnnotationView
{
    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        let hitView = super.hitTest(point, with: event)
        if (hitView != nil)
        {
            self.superview?.bringSubview(toFront: self)
        }
        return hitView
    }
    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        let rect = self.bounds;
        var isInside: Bool = rect.contains(point);
        if(!isInside)
        {
            for view in self.subviews
            {
                isInside = view.frame.contains(point);
                if isInside
                {
                    break;
                }
            }
        }
        return isInside;
    }
}

现在实现viewForannotation MapView委托如下

    extension YourViewC: MKMapViewDelegate {

        func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
            if annotation is MKUserLocation
            {
                return nil
            }
            var annotationView = self.mapView.dequeueReusableAnnotationView(withIdentifier: "CustomPin")
            if annotationView == nil{
                annotationView = AnnotationView(annotation: annotation, reuseIdentifier: "CustomPin")
                annotationView?.canShowCallout = false
            }else{
                annotationView?.annotation = annotation
            }
            annotationView?.image = UIImage(named: "bluecircle") // Pass name of your custom image
            return annotationView
        }
     func mapView(_ mapView: MKMapView,
                 didSelect view: MKAnnotationView){ 
        let annotation = view.annotation as? CustomAnnotation
       print(annotation?.address) // get info you passed on pin

      // write code here to add custom view on tapped annotion
}

答案 2 :(得分:0)

实现此目的的最佳方法是使用自定义类来存储注释。

import UIKit
import MapKit
import CoreLocation

class Annotation: NSObject, MKAnnotation {

var coordinate: CLLocationCoordinate2D = CLLocationCoordinate2D()
var title: String?
var subtitle: String?

var strTitle = ""
var strImgUrl = ""
var strDescr = ""


init(coordinates location: CLLocationCoordinate2D, title1: String, description: String, imgURL: String) {
    super.init()

    coordinate = location
    title = title1
    subtitle = description
    strTitle = title1
    strImgUrl = imgURL
    strDescr = description
}
}

现在使用此类存储注释并填充您的引脚。

//  MapViewController.swift
let myAnnotation1: Annotation = Annotation.init(coordinates: CLLocationCoordinate2D.init(latitude: 30.733051, longitude: 76.763042), title1: "The Mayflower Renaissance Hotel", description: "The Histroic hotel has been the site of saveral dramatic locations.", imgURL: "custom.jpg")
    self.uvMApView.addAnnotation(myAnnotation1)

  func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
   if (annotation is MKUserLocation) {
        return nil
    }
    // try to dequeue an existing pin view first
    let AnnotationIdentifier = "AnnotationIdentifier"

    let myAnnotation1 = (annotation as! Annotation)

    let pinView = MKAnnotationView(annotation: annotation, reuseIdentifier: AnnotationIdentifier)
    pinView.canShowCallout = true
    pinView.image = UIImage(named: myAnnotation1. strImgUrl)!
    return pinView

   }

答案 3 :(得分:0)

你也可以这样做:

    let reuseId = "pin"
    var your_pin = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView
    let your_image = UIImage (named: "your_image")

    pinView?.image = your_image
    pinView?.canShowCallout = true

我认为这是更容易回答的问题。

答案 4 :(得分:0)

花费大量时间后,我想到了一个简单的代码。
1.不要使用.pdf图片,而只能使用三种不同尺寸(例如1x,2x,3x)的.png图片。下面是我的示例代码。

@IBOutlet var mapView: MKMapView!
let locationManager = CLLocationManager()

override func viewDidLoad() {
    super.viewDidLoad()

    mapViewSetup()
}

func mapViewSetup(){
        self.locationManager.requestAlwaysAuthorization()
        // For use in foreground
        self.locationManager.requestWhenInUseAuthorization()

        if CLLocationManager.locationServicesEnabled() {
            locationManager.delegate = self
            locationManager.desiredAccuracy = kCLLocationAccuracyBest
            locationManager.startUpdatingLocation()
        }

        mapView.delegate = self
        mapView.mapType = .standard
        mapView.isZoomEnabled = true
        mapView.isScrollEnabled = true
        mapView.showsUserLocation = false

        if let coor = mapView.userLocation.location?.coordinate{
            mapView.setCenter(coor, animated: true)
        }
    }

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let locValue:CLLocationCoordinate2D = manager.location!.coordinate

        mapView.mapType = MKMapType.standard

        let span = MKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta: 0.05)
        let region = MKCoordinateRegion(center: locValue, span: span)
        mapView.setRegion(region, animated: true)

        let annotation = MKPointAnnotation()
        annotation.coordinate = locValue
        annotation.title = "Arshad"
        annotation.subtitle = "BrightSword Technologies Pvt Ltd"
        mapView.addAnnotation(annotation)

        self.locationManager.stopUpdatingLocation()

        //centerMap(locValue)
    }

private func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
        print(error.localizedDescription)
    }

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

        let annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "customannotation")
        annotationView.image = UIImage(named: "icon_location_pin")
        annotationView.canShowCallout = true

        return annotationView
    }

希望它将对某人有所帮助。