现在需要帮助。我可以使用MKPolyline和MKPolylineView绘制线,但是如何在MKMapView的两个坐标之间绘制圆弧或曲线呢?非常感谢。
最终解决方案
最后我在这里写下这些结论,以帮助想要的人。
如果您想:
所以解决方案是:
以及此处的一些提示:
阅读文档,似乎您可以创建MKOverlayPathView
的实例并将任意CGPathRef
对象分配给其path
属性。该路径可以同时包含直线和圆弧。
我不知道(并且文档中没有提到)路径的坐标应采用哪种格式(想到的是MKMapPoint
或CLLocationCoordinate2D
),但是您可以通过尝试一下来找到答案。
[您已经在评论中回答了自己,但是我想向所有人指出GitHub上出色的AIMapViewWrapper项目,其中包括sample code,用于在一组坐标上绘制弧形路径。在该项目中,它被用于绘制平面所走的路径,包括其下方的阴影路径(以及其他诸如沿该路径为平面动画等内容)的路径。对于任何对此采取刺伤的人都应该派上用场。
在回答问题之前,重要的是要提到MKOverlayView已过时,并且从iOS7开始,以后我们应该使用MKOverlayRenderer:
在iOS 7及更高版本中,请使用MKOverlayRenderer类来显示叠加层。
我们现在可以按照实现弧/曲线的方式对其进行细分:
let polyline = MKPolyline(coordinates: coordinates, count: coordinates.count)
mapView.addOverlay(polyline)
MKMapView
希望我们提供与在第1节创建的MKOverlayRenderer
相对应的适当MKPolyline
。我们需要的method是:mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer
基本上是:
向委托指定渲染器对象,以在绘制指定的叠加层时使用。
MKOverlayPathRenderer
的子类,该类显然继承自MKOverlayRenderer
并作为文档说明:当叠加层的形状由CGPath对象定义时,请使用此渲染器。默认情况下,此渲染器填充叠加层的形状,并使用其当前属性表示路径的笔触。
因此,如果我们照原样使用新的子类对象,我们将获得一个开箱即用的解决方案,它是从第1节中定义的第一个坐标到第二个坐标的实线。想要一条曲线,我们将不得不为此重写一个方法:
您可以按原样使用此类或子类来定义其他图形行为。如果您是子类,请重写createPath()方法并使用该方法来构建适当的路径对象。要更改路径,请使其无效并使用子类获得的任何新数据重新创建路径。
这意味着在我们的CustomObject: MKOverlayPathRenderer
内部,我们将覆盖createPath
:
override func createPath() {
// Getting the coordinates from the polyline
let points = polyline.points()
// Taking the center of the polyline (between the 2 coordiantes) and converting to CGPoint
let centerMapPoint = MKMapPoint(polyline.coordinate)
// Converting coordinates to CGPoint corresponding to the specified point on the map
let startPoint = point(for: points[0])
let endPoint = point(for: points[1])
let centerPoint = point(for: centerMapPoint)
// I would like to thank a co-worker of mine for the controlPoint formula :)
let controlPoint = CGPoint(x: centerPoint.x + (startPoint.y - endPoint.y) / 3,
y: centerPoint.y + (endPoint.x - startPoint.x) / 3)
// Defining our new curved path using Bezier path
let myPath = UIBezierPath()
myPath.move(to: startPoint)
myPath.addQuadCurve(to: endPoint,
controlPoint: controlPoint)
// Mutates the solid line with our curved one
path = myPath.cgPath
}
我们基本上完成了。您可能需要考虑添加宽度/笔划/颜色等,所以您可以参见曲线。
4.1。覆盖override func draw(_ mapRect: MKMapRect, zoomScale: MKZoomScale, in context: CGContext)
之后,就在添加渐变之前,您将必须从第3节中添加相同的代码,但是要更改内部path
,您必须将其添加到提供的上下文中:
context.move(to: startPoint) context.addQuadCurve(to: endPoint, control: controlPoint)
这基本上为我们提供了有关渐变着色所需的曲线。
4.2。代替使用path.boundingBoxOfPath
,我们将需要使用path.boundingBox
,因为:
... ... [[包括
贝塞尔曲线和二次曲线的控制点。与boundingBoxOfPath
不同:
...not
包括贝塞尔曲线和二次曲线的控制点。希望有所帮助:)