我正在尝试更改
MKAnnotation
内的图像而不删除圆形形状。
这里我创建了一个自定义类
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
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])
}
第一张图片是我创建的,第二张图片是我想要的。
我什至实现了
MKMapViewDelegate
:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
var annotationView = MKAnnotationView()
annotationView.image = #imageLiteral(resourceName: "heart")
return annotationView
}
这是结果:
圆形消失。
我看到很多关于如何自定义图钉的教程,但他们只解释了如何放置图像而不是图钉(如上面的壁炉图像)。我想知道如何更改图钉的图像(和颜色)并保持圆形形状(参见上面的蓝色图钉图像)。
有什么提示吗?谢谢
如果你想要圆形边框,你可以自己渲染它,或者更简单,子类
MKMarkerAnnotationView
而不是MKAnnotationView
:
class CustomAnnotationView: MKMarkerAnnotationView {
override var annotation: MKAnnotation? {
didSet { configure(for: annotation) }
}
override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
configure(for: annotation)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configure(for annotation: MKAnnotation?) {
glyphImage = ...
markerTintColor = ...
displayPriority = .required
// if doing clustering, also add
// clusteringIdentifier = ...
}
}
这样,您不仅可以获得圆形边框,还可以获得所有标记注释视图行为(显示标记下方注释视图的
title
,如果您在标记注释视图上选择,它会变大, ETC。)。如果没有必要,您可能不想从头开始编写许多标记注释视图行为。通过子类化 MKMarkerAnnotationView
而不是普通的 MKAnnotationView
,你可以免费获得所有这些行为。
例如,您可以:
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)
configure(for: annotation)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configure(for annotation: MKAnnotation?) {
glyphImage = Self.glyphImage
markerTintColor = #colorLiteral(red: 0.005868499167, green: 0.5166643262, blue: 0.9889912009, alpha: 1)
displayPriority = .required
// if doing clustering, also add
// clusteringIdentifier = ...
}
}
结果:
显然,当你设置
glyphImage
时,将其设置为你想要的任何图像。旧的 SF Symbols 没有那个“drop”图像(尽管 iOS 14 有 drop.fill
)。但请提供您想要的任何 40 × 40 pt 图像视图。我自己渲染它,但您可以使用您想要的资产目录(或系统符号)中任何适当大小的图像。
顺便说一句,从 iOS 11 开始,你通常根本不会实现
mapView(_:viewFor:)
,除非绝对必要(在本例中并非如此)。例如,您可以摆脱 viewFor
方法,只需在 viewDidLoad
中注册自定义注释视图:
override func viewDidLoad() {
super.viewDidLoad()
mapView.register(CustomAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)
...
}