[英]How to draw arc/curve line with MKOverlayView on MKMapView
現在需要幫助。 我可以用 MKPolyline 和 MKPolylineView 畫線,但是如何在 MKMapView 上的兩個坐標之間畫弧線或曲線? 萬分感謝。
您已經在評論中回答了自己,但我想向大家指出 GitHub 上優秀的AIMapViewWrapper項目,其中包括用於在一組坐標上繪制圓弧路徑的示例代碼。 在那個項目中,它被用來繪制平面所采用的路徑,包括它下面的陰影路徑(以及其他東西,例如沿該路徑為平面設置動畫)。 任何人都應該派上用場。
閱讀文檔,似乎您可以創建MKOverlayPathView
的實例並將任意CGPathRef
對象分配給其path
屬性。 該路徑可以包含直線和圓弧。
我不知道(並且文檔沒有提到)路徑的坐標應該是什么格式( MKMapPoint
或CLLocationCoordinate2D
),但您可能可以通過一些試驗找到MKMapPoint
。
在回答這個問題之前,重要的是要提到MKOverlayView已被棄用,並且從 iOS7 和更高版本開始,我們應該使用MKOverlayRenderer :
在 iOS 7 及更高版本中,請改用 MKOverlayRenderer 類來顯示疊加層。
我們現在可以將其分解為如何實現圓弧/曲線線:
let polyline = MKPolyline(coordinates: coordinates, count: coordinates.count)
mapView.addOverlay(polyline)
MKMapView
會要求我們提供一個合適的MKOverlayRenderer
對應於我們在第 1 部分創建的MKPolyline
。我們需要的方法是: 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
不同:
...不包括貝塞爾曲線和二次曲線的控制點。
希望有幫助:)
如果你想:
所以解決辦法是:
還有一些提示:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.