Есть ли способ переместить оверлей MKCircle с помощью MKUserLocation, не щелкая и не мигая? - PullRequest
0 голосов
/ 13 марта 2020

В настоящее время я использую этот код для рисования круга.

func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
    if let overlay = overlay as? MKCircle {
        let circleRenderer = MKCircleRenderer(overlay: overlay)
        circleRenderer.fillColor = UIColor.black.withAlphaComponent(0.19)
        circleRenderer.lineWidth = 1
        return circleRenderer
    }
    return MKOverlayRenderer(overlay: overlay)
}

func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) {
    let circle = MKCircle(center: userLocation.coordinate, radius: self.regionRadius)
    print("\(userLocation.coordinate)")

    if (CLLocationManager.authorizationStatus() == .denied || CLLocationManager.authorizationStatus() == .notDetermined)  {
        mapView.removeOverlays(mapView.overlays)
    } else {
        mapView.removeOverlays(mapView.overlays)
        mapView.addOverlay(circle)
    }
}

Токовый выход:

enter image description here

Работает нормально, но круг мигает и мигает. Мне нужно плавное движение по кругу. Я знаю, что это проблема iOS 13.

1 Ответ

0 голосов
/ 07 апреля 2020

Существует два варианта:

  1. Я обнаружил, что, как правило, эффект мерцания уменьшается, если вы добавляете новое наложение перед удалением старого.

  2. Возможно, вы захотите сделать круг в виде пользовательского аннотации, а не наложения. Таким образом, вы можете просто настроить coordinate, не добавляя и не удаляя.

Помещая круг в аннотацию, она становится бесшовной, как при отслеживании пользователя:

enter image description here

Я отключил отслеживание пользователей на полпути, чтобы вы могли видеть оба шаблона.

class CirclePointerAnnotationView: MKAnnotationView {
    let circleShapeLayer: CAShapeLayer = {
        let shapeLayer = CAShapeLayer()
        shapeLayer.fillColor = UIColor.lightGray.withAlphaComponent(0.25).cgColor
        shapeLayer.strokeColor = UIColor.clear.cgColor
        return shapeLayer
    }()

    let pinShapeLayer: CAShapeLayer = {
        let shapeLayer = CAShapeLayer()
        shapeLayer.fillColor = UIColor.blue.cgColor
        shapeLayer.strokeColor = UIColor.clear.cgColor
        return shapeLayer
    }()

    let imageView: UIImageView = {
        let imageView = UIImageView()
        imageView.contentMode = .scaleAspectFill
        imageView.image = UIImage(named: "woman")
        imageView.clipsToBounds = true
        return imageView
    }()

    var pinHeight: CGFloat = 100
    var pinRadius: CGFloat = 30
    var annotationViewSize = CGSize(width: 300, height: 300)

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

        layer.addSublayer(circleShapeLayer)
        layer.addSublayer(pinShapeLayer)
        addSubview(imageView)

        bounds.size = annotationViewSize
    }

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

    override func layoutSubviews() {
        let radius = min(bounds.width, bounds.height) / 2
        let center = CGPoint(x: bounds.midX, y: bounds.midY)
        circleShapeLayer.path = UIBezierPath(arcCenter: center, radius: radius, startAngle: 0, endAngle: 2 * .pi, clockwise: true).cgPath

        let angle = asin(pinRadius / (pinHeight - pinRadius))
        let pinCenter = CGPoint(x: center.x, y: center.y - (pinHeight - pinRadius))
        let path = UIBezierPath()
        path.move(to: center)
        path.addArc(withCenter: pinCenter, radius: pinRadius, startAngle: .pi - angle, endAngle: angle, clockwise: true)
        path.close()
        pinShapeLayer.path = path.cgPath

        let imageViewDimension = pinRadius * 2 - 15
        imageView.bounds.size = CGSize(width: imageViewDimension, height: imageViewDimension)
        imageView.center = pinCenter
        imageView.layer.cornerRadius = imageViewDimension / 2
    }
}
...