Изменить размер MKMarkerAnnotationView - PullRequest
1 голос
/ 02 мая 2020

Как изменить 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
}

1 Ответ

1 голос
/ 02 мая 2020

См. glyphImage документацию , в которой говорится о размере глифа:

Изображение глифа отображается, когда маркер находится в нормальном состоянии. Создайте изображения глифов как изображения шаблонов, чтобы к нему можно было применить цветовой оттенок глифа. Обычно вы устанавливаете размер этого изображения на 20 на 20 точек на iOS и 40 на 40 точек на tvOS. Однако, если вы не предоставляете отдельное выбранное изображение в свойстве selectedGlyphImage, задайте размер этого изображения 40 на 40 точек на iOS и 60 на 40 точек на tvOS. MapKit масштабирует изображения, которые больше или меньше, чем эти размеры.

В итоге, 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")
    }
}

Кстати, я бы предложил зарегистрировать этот класс представлений аннотации, как показано ниже, а затем полностью удалить метод 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
    }
}

Это дает:

enter image description here

Но даже это не воспроизводит все MKMarkerAnnotationView поведения. Таким образом, все сводится к тому, сколько из MKMarkerAnnotationView типов поведения / внешнего вида вам нужно, и стоит ли иметь все эти усилия для увеличения аннотации.

...