更改 MKMarkerAnnotationView 大小

Change MKMarkerAnnotationView size

如何更改MKMarkerAnnotationView尺寸?

我尝试设置 annotationView.bounds.size = CGSize(width: 50, height: 50),但尺寸似乎没有变化。我还尝试打印出视图的大小,看起来它默认为 28,28

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
      guard annotation is MKPointAnnotation else { return nil }


      let annotationView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: Constant.Indentifier.mapPoint)
      annotationView.canShowCallout = true
      annotationView.animatesWhenAdded = true
      annotationView.glyphImage = UIImage(systemName: "house.fill")
      annotationView.glyphTintColor = .systemBlue
      annotationView.markerTintColor = .white
      print(annotationView.bounds.size) // defaulted to 28,28
      annotationView.bounds.size = CGSize(width: 50, height: 50) // Does not change bubble size
      return annotationView
}

glyphImagedocumentation,里面讲到了字形的大小:

The glyph image is displayed when the marker is in the normal state. Create glyph images as template images so that the glyph tint color can be applied to it. Normally, you set the size of this image to 20 by 20 points on iOS and 40 by 40 points on tvOS. However, if you do not provide a separate selected image in the selectedGlyphImage property, make the size of this image 40 by 40 points on iOS and 60 by 40 points on tvOS instead. MapKit scales images that are larger or smaller than those sizes.

最重要的是,MKMarkerAnnotationView 有两种状态的固定大小,选中和未选中。

如果您想要更大的注释视图,您需要编写自己的 MKAnnotationView。例如,简单地创建一个大房子图像相对容易:

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

        let configuration = UIImage.SymbolConfiguration(pointSize: 50)
        image = UIImage(systemName: "house.fill", withConfiguration: configuration)
    }

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

顺便说一句,我建议像下面这样注册这个注释视图 class,然后完全删除 mapView(_:viewFor:) 方法。

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

现在,上面的注释视图只渲染了一个大的“房子”图像。如果你想要它在气泡中,就像 MKMarkerAnnotationView 那样,你必须自己画:

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

        configureImage()
        configureView()
        configureAnnotationView()
    }

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

private extension HouseAnnotationView {
    func configureImage() {
        let radius: CGFloat = 25
        let center = CGPoint(x: radius, y: radius)
        let rect = CGRect(origin: .zero, size: CGSize(width: 50, height: 60))
        let angle: CGFloat = .pi / 16

        let image = UIGraphicsImageRenderer(bounds: rect).image { _ in
            UIColor.white.setFill()
            let path = UIBezierPath(arcCenter: center, radius: radius, startAngle: .pi / 2 - angle, endAngle: .pi / 2 + angle, clockwise: false)
            path.addLine(to: CGPoint(x: rect.midX, y: rect.maxY))
            path.close()
            path.fill()

            let configuration = UIImage.SymbolConfiguration(pointSize: 24)
            let house = UIImage(systemName: "house.fill", withConfiguration: configuration)!
                .withTintColor(.blue)
            house.draw(at: CGPoint(x: center.x - house.size.width / 2, y: center.y - house.size.height / 2))
        }

        self.image = image
        centerOffset = CGPoint(x: 0, y: -image.size.height / 2) // i.e. bottom center of image is where the point is
    }

    func configureView() {
        layer.shadowColor = UIColor.black.cgColor
        layer.shadowRadius = 5
        layer.shadowOffset = CGSize(width: 3, height: 3)
        layer.shadowOpacity = 0.5
    }

    func configureAnnotationView() {
        canShowCallout = true
    }
}

产生:

但即使那样也不能重现所有 MKMarkerAnnotationView 行为。所以这一切都归结为您需要多少 MKMarkerAnnotationView behaviors/appearance 以及拥有更大的注释视图是否值得所有这些努力。