Swift - MKAnnotationView 地图引脚的自定义 UIView

Posted

技术标签:

【中文标题】Swift - MKAnnotationView 地图引脚的自定义 UIView【英文标题】:Swift - Custom UIView for MKAnnotationView map pin 【发布时间】:2018-07-04 21:18:59 【问题描述】:

如何为MKAnnotationView 设置自定义视图?我希望我的地图别针通过UIView 看起来独一无二。 UIView 子类中可能有我想要自定义的其他视图。

网上有很多关于如何设置注释图像的例子,但没有如何实际更改该注释:

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView?
    
        if !(annotation is MKPointAnnotation) 
            return nil
        

        let annotationIdentifier = "AnnotationIdentifier"
        var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(annotationIdentifier)

        if annotationView == nil 
            annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: annotationIdentifier)
            annotationView!.canShowCallout = true
        
        else 
            annotationView!.annotation = annotation
        

        let pinImage = UIImage(named: "customPinImage")
        annotationView!.image = pinImage

       return annotationView   
    

【问题讨论】:

【参考方案1】:

MKAnnotationView 是 UIView 的一个子类,它本身可以被子类化。

所以你只需要继承 MKAnnotationView。

自定义子视图

这是一个显示蓝色三角形的简单示例。既然您提到 UIView 自定义子类中应该有其他视图,我添加了一个应该显示数字的标签。

class CustomAnnotationView: MKAnnotationView 
    private let annotationFrame = CGRect(x: 0, y: 0, width: 40, height: 40)
    private let label: UILabel

    override init(annotation: MKAnnotation?, reuseIdentifier: String?) 
        self.label = UILabel(frame: annotationFrame.offsetBy(dx: 0, dy: -6))
        super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
        self.frame = annotationFrame
        self.label.font = UIFont.systemFont(ofSize: 24, weight: .semibold)
        self.label.textColor = .white
        self.label.textAlignment = .center
        self.backgroundColor = .clear
        self.addSubview(label)
    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) not implemented!")
    

    public var number: UInt32 = 0 
        didSet 
            self.label.text = String(number)
        
    

    override func draw(_ rect: CGRect) 
        guard let context = UIGraphicsGetCurrentContext() else  return 

        context.beginPath()
        context.move(to: CGPoint(x: rect.midX, y: rect.maxY))
        context.addLine(to: CGPoint(x: rect.maxX, y: rect.minY))
        context.addLine(to: CGPoint(x: rect.minX, y: rect.minY))
        context.closePath()

        UIColor.blue.set()
        context.fillPath()
    


MKMapViewDelegate 方法

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

    guard annotation is MKPointAnnotation else  return nil 

    let customAnnotationView = self.customAnnotationView(in: mapView, for: annotation)
    customAnnotationView.number = arc4random_uniform(10)
    return customAnnotationView

自定义注解视图

private func customAnnotationView(in mapView: MKMapView, for annotation: MKAnnotation) -> CustomAnnotationView 
    let identifier = "CustomAnnotationViewID"

    if let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? CustomAnnotationView 
        annotationView.annotation = annotation
        return annotationView
     else 
        let customAnnotationView = CustomAnnotationView(annotation: annotation, reuseIdentifier: identifier)
        customAnnotationView.canShowCallout = true
        return customAnnotationView
    

结果

结果如下所示:

【讨论】:

【参考方案2】:

我之前使用UIView 来注释MKAnnotationView。我通过将视图作为子视图添加到MKAnnotationView 来做到这一点,但很快发现在我的地图上渲染大量注释时这会导致大量内存问题。相反,我恢复构建一个由我的不同子视图组成的UIView,然后将其转换为UIImage,并将其分配给MKAnnotationViewimage 属性。

这里是 a link 到 Stack Overflow 的答案,这将有助于 UIViewUIImage 的转换。

【讨论】:

好主意!您发现将 UIView 转换为 UIImage 并没有那么昂贵的内存吗? @Micro Ohh 绝对。有时我的地图会渲染 200 多个注释,而使用自定义视图会严重减慢速度。删除我对UIView 的使用并使用MKAnnotationimage 属性减少了我的内存占用。实施地图别针聚类进一步减少了它。 在我的部分观点中,我想从 url 加载图像 - 我担心使用您的方法,图像在转换为 image 并设置为 @ 之前可能无法从 url 加载987654337@'s image .. 你会下载很多不同的图片吗?如果不是,我会在地图上渲染注释之前下载单个图像

以上是关于Swift - MKAnnotationView 地图引脚的自定义 UIView的主要内容,如果未能解决你的问题,请参考以下文章

Swift - MKAnnotationView 地图引脚的自定义 UIView

使用 MKZoomScale 调整 MKAnnotationView 的大小 - Swift 2.0

拖动我的 MKAnnotationView 后拖动地图不会移动 MKAnnotationView

自定义 iOS8 标注气泡 (Swift)

如何为 MKAnnotationView 放置动画?

- (MKAnnotationView *)mapView 没有被调用