Существует два варианта:
Я обнаружил, что, как правило, эффект мерцания уменьшается, если вы добавляете новое наложение перед удалением старого.
Возможно, вы захотите сделать круг в виде пользовательского аннотации, а не наложения. Таким образом, вы можете просто настроить coordinate
, не добавляя и не удаляя.
Помещая круг в аннотацию, она становится бесшовной, как при отслеживании пользователя:
Я отключил отслеживание пользователей на полпути, чтобы вы могли видеть оба шаблона.
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
}
}