【问题标题】:How to add custom images to annotations in Mapview Swift ios?如何在 Mapview Swift ios 中将自定义图像添加到注释中?
【发布时间】:2017-05-11 12:54:47
【问题描述】:
 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 注释方法中调用它。我怎样才能做到这一点?

【问题讨论】:

标签: ios swift3 mkmapview mkannotation


【解决方案1】:

答案如下:

斯威夫特 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
}

斯威夫特 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
}

【讨论】:

  • 仍然没有加载图像。
  • @Rakesh 您使用的是哪个版本的 swift?您能否检查一下您的图片资产中的图片退出情况。因为我还检查了上面的代码,所以它显示了我的图像
  • 我正在使用 swift3。我的图片存在于资产中。
【解决方案2】:

斯威夫特 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)

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

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
}

【讨论】:

    【解决方案3】:

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

    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
    
       }
    

    【讨论】:

    • 仍然没有加载图像@Ankit Saini
    • 您尝试加载的图像在您的应用程序包中,或者您正在从某个 URL 加载它?如果这是服务器图像,那么您必须替换 { pinView.image = UIImage(named: myAnnotation1.strImgUrl)! }.
    • 它在我的项目中。
    【解决方案4】:

    花了很多时间后,我想出了一个简单的代码。
    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
        }
    

    希望对某人有所帮助。

    【讨论】:

      【解决方案5】:

      你也可以这样做:

          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
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-22
        • 2017-06-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多