如何自定义 MKAnnotation pin 的图像 [英] How to custom the image of 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屋!