如何自定义 MKAnnotation pin 的图像 [英] How to custom the image of MKAnnotation pin

查看:167
本文介绍了如何自定义 MKAnnotation pin 的图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试更改 MKAnnotation 内的图像而不删除圆形.

I am trying to change the image that is inside the MKAnnotation without removing the rounded shape.

这里我创建了一个MKAnnotation的自定义类:

Here I create a custom class of MKAnnotation:

class MapPin: NSObject, MKAnnotation {
    let title: String?
    let locationName: String
    let coordinate: CLLocationCoordinate2D
    init(title: String, locationName: String, coordinate: CLLocationCoordinate2D) {
        self.title = title
        self.locationName = locationName
        self.coordinate = coordinate
    }
}

这里我创建了一个 MapPin 并将其添加到 mapView

Here I create a MapPin and I add it to the mapView

func setPinUsingMKAnnotation() {
   let pin1 = MapPin(title: "Here", locationName: "Device Location", coordinate: CLLocationCoordinate2D(latitude: 21.283921, longitude: -157.831661))
   let coordinateRegion = MKCoordinateRegion(center: pin1.coordinate, latitudinalMeters: 800, longitudinalMeters: 800)
   mapView.setRegion(coordinateRegion, animated: true)
   mapView.addAnnotations([pin1])
}

第一张图片是我创建的,第二张图片是我想要的.

The first image is what I created, the second image is what I would like it to be.

我什至实现了MKMapViewDelegate:

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    var annotationView = MKAnnotationView()
    annotationView.image = #imageLiteral(resourceName: "heart")
    return annotationView
}

结果如下:

圆形消失.

我看过很多关于如何自定义图钉的教程,但他们只解释了如何放置图像而不是图钉(如上面的壁炉图像).我想知道如何更改图钉的图像(和颜色)并保持圆形(参见上面的蓝色图钉图像).

I saw many tutorials about how to custom a pin, but they only explained how to put an image instead of the pin (like the hearth image above). I would like to know how to change the image (and color) of the pin and keep the rounded shape (see the blue pin image above).

有什么提示吗?谢谢

推荐答案

如果你想要圆角边框,你可以自己渲染,或者更容易,子类 MKMarkerAnnotationView 而不是 MKAnnotationView代码>:

If you want that rounded border, you can render it yourself, or easier, subclass MKMarkerAnnotationView rather than MKAnnotationView:

class CustomAnnotationView: MKMarkerAnnotationView {
    override var annotation: MKAnnotation? {
        didSet { configure(for: annotation) }
    }

    override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
        super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)

        glyphImage = ...
        markerTintColor = ...
            
        configure(for: annotation)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func configure(for annotation: MKAnnotation?) {
        displayPriority = .required

        // if doing clustering, also add
        // clusteringIdentifier = ...
    }
}

这样,您不仅可以获得圆形边框,还可以获得所有标记注释视图行为(如果您在标记上选择,则在标记下方显示注释视图的 title注释视图,它变得更大,等等).如果不需要,您可能不想从头开始编写许多标记注释视图行为.通过继承 MKMarkerAnnotationView 而不是普通的 MKAnnotationView,您可以免费获得所有这些行为.

That way, not only do you get the circular border, but you get all of the marker annotation view behaviors (shows the title of the annotation view below the marker, if you select on the marker annotation view, it becomes larger, etc.). There’s a lot of marker annotation view behaviors that you probably don’t want to have to write from scratch if you don’t have to. By subclassing MKMarkerAnnotationView instead of the vanilla MKAnnotationView, you get all those behaviors for free.

例如,您可以:

class CustomAnnotationView: MKMarkerAnnotationView {
    static let glyphImage: UIImage = {
        let rect = CGRect(origin: .zero, size: CGSize(width: 40, height: 40))
        return UIGraphicsImageRenderer(bounds: rect).image { _ in
            let radius: CGFloat = 11
            let offset: CGFloat = 7
            let insetY: CGFloat = 5
            let center = CGPoint(x: rect.midX, y: rect.maxY - radius - insetY)
            let path = UIBezierPath(arcCenter: center, radius: radius, startAngle: 0, endAngle: .pi, clockwise: true)
            path.addQuadCurve(to: CGPoint(x: rect.midX, y: rect.minY + insetY), controlPoint: CGPoint(x: rect.midX - radius, y: center.y - offset))
            path.addQuadCurve(to: CGPoint(x: rect.midX + radius, y: center.y), controlPoint: CGPoint(x: rect.midX + radius, y: center.y - offset))
            path.close()
            UIColor.white.setFill()
            path.fill()
        }
    }()

    override var annotation: MKAnnotation? {
        didSet { configure(for: annotation) }
    }

    override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
        super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)

        glyphImage = Self.glyphImage
        markerTintColor = #colorLiteral(red: 0.005868499167, green: 0.5166643262, blue: 0.9889912009, alpha: 1)

        configure(for: annotation)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func configure(for annotation: MKAnnotation?) {
        displayPriority = .required

        // if doing clustering, also add
        // clusteringIdentifier = ...
    }
}

结果:

显然,当您设置 glyphImage 时,请将其设置为您想要的任何图像.旧的 SF Symbols 没有那个drop"图像(尽管 iOS 14 有 drop.fill).但是提供您想要的任何 40 × 40 pt 图像视图.我正在自己渲染它,但您可以使用您想要的资产目录(或系统符号)中任何适当大小的图像.

Obviously, when you set glyphImage, set it to whatever image you want. The old SF Symbols doesn't have that "drop" image (though iOS 14 has drop.fill). But supply whatever 40 × 40 pt image view you want. I'm rendering it myself, but you can use whatever appropriately sized image from your asset catalog (or from the system symbols) that you want.

顺便说一句,从 iOS 11 开始,您通常根本不会实现 mapView(_:viewFor:) ,除非绝对必要(在这种情况下并非如此).例如,你可以去掉你的 viewFor 方法,只在 viewDidLoad 中注册你的自定义注解视图:

As an aside, since iOS 11, you wouldn't generally wouldn't implement mapView(_:viewFor:) at all, unless absolutely necessary (which it isn't in this case). For example, you can get rid of your viewFor method and just register your custom annotation view in viewDidLoad:

override func viewDidLoad() {
    super.viewDidLoad()

    mapView.register(CustomAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)

    ...
}

这篇关于如何自定义 MKAnnotation pin 的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆