MapKit中如何将MKAnnotation对齐到MKCircle覆盖层底部居中位置
实现方案
你需要完成以下三处调整即可实现标注始终在圆形覆盖层底部居中、二者同步缩放显示为整体的效果:
1. 计算圆形底部居中的标注地理坐标
MKCircle的地理半径固定,你只需要将圆心坐标向南偏移和半径相等的距离,得到的坐标就是圆形底部的居中位置:
// 示例:创建圆形覆盖层时同步计算标注坐标 let circleCenter = CLLocationCoordinate2D(latitude: 目标纬度, longitude: 目标经度) let circleRadius: CLLocationDistance = 500 // 你的圆形半径,单位为米 let circle = MKCircle(center: circleCenter, radius: circleRadius) // 计算标注坐标:纬度向南偏移半径对应的度数,经度保持和圆心一致 let annotationCoordinate = CLLocationCoordinate2D( latitude: circleCenter.latitude - (circleRadius / 111319.9), // 纬度每度对应约111319.9米 longitude: circleCenter.longitude ) // 用计算出的坐标初始化你的标注 let glueAnnotation = GlueAnnotation(coordinate: annotationCoordinate, title: "你的标签文本") mapView.addAnnotation(glueAnnotation)
如果你的圆形半径会动态修改,每次修改半径后重新计算上述坐标、调用glueAnnotation.setCoordinate(新坐标)更新即可。
2. 调整自定义AnnotationView的锚点
默认MKAnnotationView的锚点在视图中心,你需要将锚点修改为视图顶部的中点,让标注的顶部边缘刚好对齐圆形的底部坐标,不会出现错位:
在你的MyAnnotationView的init方法中添加如下代码:
// 放在设置self.frame的代码之后即可 self.layer.anchorPoint = CGPoint(x: 0.5, y: 0)
3. 修复自定义覆盖层渲染器的代码问题
你当前的InvertedCircleOverlayRenderer中直接将地理坐标作为视图坐标使用,会导致圆形渲染异常,修改draw方法如下:
public override func draw(_ mapRect: MKMapRect, zoomScale: MKZoomScale, in context: CGContext) { let fullPath = UIBezierPath(rect: rect(for: MKMapRect.world)) // 转换圆形的地图矩形为当前上下文的视图矩形 let circleViewRect = rect(for: circle.boundingMapRect) let circlePath = UIBezierPath(roundedRect: circleViewRect, cornerRadius: circleViewRect.width / 2) // 反转圆形路径保证evenOdd模式下正确挖空 fullPath.append(circlePath.reversing()) context.setFillColor(fillColor.cgColor) context.addPath(fullPath.cgPath) context.fillPath(using: .evenOdd) context.addPath(circlePath.cgPath) context.setLineWidth(lineWidth / zoomScale) context.setStrokeColor(strokeColor.cgColor) context.strokePath() }
完成以上修改后,标注会始终固定在圆形覆盖层的底部居中位置,随地图缩放时二者会保持相对位置不变,呈现为统一整体。
内容的提问来源于stack exchange,提问作者Luigi Trevisi
相关产品推荐
相关产品推荐

