自定义 MKMarkerAnnotationView Like Photos 应用程序

Koh*_*Koh 6 swift

我正在尝试创建一个自定义 pinView,就像照片应用程序的操作方式一样:

在此输入图像描述

到目前为止,我可以在 SO 或此处此处找到的大多数资源都显示了自定义图钉图像或标注视图的方法,但没有关于标记本身的自定义视图的资源。

最终,我想要实现的目标类似于照片应用程序,其中标记本身上显示的每个图像都是用户的个人资料图像,但是是圆形视图。到目前为止我的代码非常基本:

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "pin") as? MKMarkerAnnotationView
        
        if annotationView == nil {
            annotationView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: "pin")
            annotationView?.canShowCallout = true
            annotationView?.leftCalloutAccessoryView = UIImageView(image: UIImage(named: "profileImage"))
        } else {
            annotationView?.annotation = annotation
        }
        
        return annotationView
    }
Run Code Online (Sandbox Code Playgroud)

我真的已经用尽了网上资源搜索。接下来我可以尝试什么?

小智 5

您可以实现任何您想要的自定义设计,您只需要提供一个名为 viewFor 的委托方法。

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: "pin", for: annotation)
    pinView = MapPinView(annotation: annotation, reuseIdentifier: "pin")
    return pinView
}
Run Code Online (Sandbox Code Playgroud)

在 viewDidload 方法中将 MapView 委托设置为 self,当然也可以像下面这样注册您的自定义视图。

override func viewDidLoad() {
   super.viewDidLoad()
   mapView.delegate = self
   mapView.register(MapPinView.self, forAnnotationViewWithReuseIdentifier: "pin")
}
Run Code Online (Sandbox Code Playgroud)

自定义视图可以如下所示。

import MapKit

class MapPinView: MKAnnotationView {
    private lazy var containerView: UIView = {
        let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
        view.backgroundColor = .white
        view.layer.cornerRadius = 16.0
        return view
    }()
    
    private lazy var imageView: UIImageView = {
        let imageview = UIImageView()
        imageview.translatesAutoresizingMaskIntoConstraints = false
        imageview.image = UIImage(named: "bg")
        imageview.layer.cornerRadius = 8.0
        imageview.clipsToBounds = true
        return imageview
    }()
    
    private lazy var bottomCornerView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = .white
        view.layer.cornerRadius = 4.0
        return view
    }()
    
    // MARK: Initialization
    override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
        super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
        setupView()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupView() {
        containerView.addSubview(bottomCornerView)
        bottomCornerView.topAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -15.0).isActive = true
        bottomCornerView.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true
        bottomCornerView.widthAnchor.constraint(equalToConstant: 24).isActive = true
        bottomCornerView.heightAnchor.constraint(equalToConstant: 24).isActive = true
        
        let angle = (39.0 * CGFloat.pi) / 180
        let transform = CGAffineTransform(rotationAngle: angle)
        bottomCornerView.transform = transform
        
        addSubview(containerView)
        containerView.addSubview(imageView)
        imageView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 8.0).isActive = true
        imageView.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 8.0).isActive = true
        imageView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -8.0).isActive = true
        imageView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -8.0).isActive = true
    }
}
Run Code Online (Sandbox Code Playgroud)

我的看起来像这样。 在此输入图像描述