带有默认地图视图引脚的 Swift Mapview 自定义调出视图

Posted

技术标签:

【中文标题】带有默认地图视图引脚的 Swift Mapview 自定义调出视图【英文标题】:Swift Mapview Custom Call Out View with default map view pins 【发布时间】:2018-09-30 22:20:50 【问题描述】:

我相信这将是一个非常简单的答案,但我一直在尝试弄清楚如何使用地图视图默认图钉添加自定义标注视图。使用我当前的代码,我似乎只能将图像添加为 MKPointAnnotation 而不是默认引脚。这第一个“viewFor 注释”是我设置默认引脚的方式,而下面的所有内容都是用于自定义标注视图......我想要做的是让我的自定义标注视图带有默认引脚。如果我想要自定义调出视图,是否必须添加自定义图像图钉?

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

    if let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "") 
        annotationView.annotation = annotation
        return annotationView
     else 
        let annotationView = MKPinAnnotationView(annotation:annotation, reuseIdentifier:"")
        annotationView.isEnabled = true
        annotationView.canShowCallout = true

        let btn = UIButton(type: .detailDisclosure)
        annotationView.rightCalloutAccessoryView = btn
        return annotationView
    



func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? 

    if annotation is MKUserLocation  return nil 
    var annotationView = self.mapView.dequeueReusableAnnotationView(withIdentifier: "Pin")
    if annotationView == nil
        annotationView = CustomBusinessCallOutAnnotatiion(annotation: annotation, reuseIdentifier: "Pin")
        annotationView?.canShowCallout = false
    else
        annotationView?.annotation = annotation
    
    annotationView?.image = UIImage(named: "car")
    return annotationView


func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) 

    if view.annotation is MKUserLocation  return 

    let customAnnotation = view.annotation as! CustomBusinessPoint
    let views = Bundle.main.loadNibNamed("CustomBusinessCallOut", owner: nil, options: nil)
    let calloutView = views?[0] as! CustomBusinessCallOut


    calloutView.businessName.text = customAnnotation.businessName
    calloutView.businessStreet.text = customAnnotation.businessStreet
    calloutView.businessState.text = customAnnotation.businessState
    calloutView.businessDistance.text = customAnnotation.businessDistance


    calloutView.center = CGPoint(x: view.bounds.size.width / 2, y: -calloutView.bounds.size.height * -0.0001)
    view.addSubview(calloutView)
    mapView.setCenter((view.annotation?.coordinate)!, animated: true)


func mapView(_ mapView: MKMapView, didDeselect view: MKAnnotationView) 
    if view.isKind(of: CustomBusinessCallOutAnnotatiion.self) 
        for subview in view.subviews 
            subview.removeFromSuperview()
        
    

【问题讨论】:

你可以使用annotationView.detailCalloutAccessoryView 【参考方案1】:

你不需要添加SubView calloutView。您可以使用MKAnnotationView 作为自定义标注。

例如你应该安排源代码

实现MKAnnotationMKAnnotationView 的子类。

class PinAnnotation : NSObject, MKAnnotation 
    var coordinate : CLLocationCoordinate2D
    var title: String?
    var calloutAnnotation: CustomBusinessCallOut?

    init(location coord:CLLocationCoordinate2D) 
        self.coordinate = coord
        super.init()
    


class CustomBusinessCallOut : NSObject, MKAnnotation 
    var coordinate: CLLocationCoordinate2D
    var title: String?

    init(location coord:CLLocationCoordinate2D) 
        self.coordinate = coord
        super.init()
    


class CalloutAnnotationView : MKAnnotationView 

实现 mapView 委托方法。

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

    if annotation is PinAnnotation 
        let reuseId = "Pin"
        var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId) as? MKPinAnnotationView
        if pinView == nil 
            pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
        
        else 
            pinView?.annotation = annotation
        

        return pinView
     else if annotation is CustomBusinessCallOut 
        let reuseId = "Callout"
        var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId)
        if pinView == nil 
            pinView = CalloutAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
            pinView?.addSubview(UIImageView(image: UIImage(named: "car")))
        
        else 
            pinView?.annotation = annotation
        

        return pinView
     else 
        return nil
    


func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) 
    guard view.annotation is PinAnnotation else  return 
    if let pinAnnotation = view.annotation as? PinAnnotation 
        let calloutAnnotation = CustomBusinessCallOut(location: pinAnnotation.coordinate)
        calloutAnnotation.title = pinAnnotation.title
        pinAnnotation.calloutAnnotation = calloutAnnotation
        mapView.addAnnotation(calloutAnnotation)
    


func mapView(_ mapView: MKMapView, didDeselect view: MKAnnotationView) 
    guard view.annotation is PinAnnotation else  return 
    if let pinAnnotation = view.annotation as? PinAnnotation,
        let calloutAnnotation = pinAnnotation.calloutAnnotation 
        mapView.removeAnnotation(calloutAnnotation)
        pinAnnotation.calloutAnnotation = nil
    

【讨论】:

以上是关于带有默认地图视图引脚的 Swift Mapview 自定义调出视图的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 3 中的 mapview 上生成不同的图钉?

在不同的引脚上显示自定义和默认标注视图,并在地图视图上进行引脚聚类

在 Swift 中的同一个 mapView 中分配多个注释 pinColors?

带有工具栏的 Mapview,如默认地图 iphone

Swift 3 Firebase 到 MapKit

Swift MKMapView 引脚注释问题