How to draw UIBezierPath identical to MKPolyline in a UIView

后端 未结 2 950
情话喂你
情话喂你 2021-01-06 07:47

Currently I am tracking my location on an MKMapView. My objective is to draw a bezier path identical to an MKPolyline created from tracked locations.

What I have att

2条回答
  •  时光取名叫无心
    2021-01-06 08:49

    this might help you, in case you haven't solved it yet.

    I wanted the shape of an MKPolyline as an image without any background. I used the code above as an inspiration and had the same troubles as you had, the route was not shown.

    In fact it was kind a scaling problem I think. At least it looked like that in the playground. Anyway, with this methods I get an image of the polylines shape.

    private func createPolylineShapeAsImage() -> UIImage? {
        let vw = UIView(frame: mapView.bounds)
        var image : UIImage?
        if let polyline = viewModel.tourPolyline {
            let path = createBezierPath(mapView, polyline, to: mapView)
            let layer = getShapeLayer(path: path, lineColor: UIColor.white, fillColor: .clear)
            vw.layer.addSublayer(layer)
            image = vw.asImage()
        }
        return image
    }
    
    func createBezierPath(_ mapView : MKMapView, _ polyline : MKPolyline, to view : UIView) -> UIBezierPath  {
        let mapPoints = polyline.points()
        var points = [CGPoint]()
        let max = polyline.pointCount - 1
        for point in 0...max {
           let coordinate = mapPoints[point].coordinate
           points.append(mapView.convert(coordinate, toPointTo: view))
        }
        let path = UIBezierPath(points: points)
        path.lineWidth = 5.0
        return path
    }
    
    private func getShapeLayer(path:UIBezierPath, lineColor:UIColor, fillColor:UIColor) -> CAShapeLayer {
        let layer = CAShapeLayer()
        layer.path = path.cgPath
        layer.strokeColor = lineColor.cgColor
        layer.fillColor = fillColor.cgColor
        layer.lineWidth = path.lineWidth
    
        layer.opacity = 1
        layer.frame = path.bounds
        return layer
    }
    

    And to get the image of the view use this extension

    import UIKit
    extension UIView {
      // Using a function since `var image` might conflict with an existing variable
      // (like on `UIImageView`)
      func asImage() -> UIImage {
        if #available(iOS 10.0, *) {
            let renderer = UIGraphicsImageRenderer(bounds: bounds)
            return renderer.image { rendererContext in
                layer.render(in: rendererContext.cgContext)
            }
        } else {
            UIGraphicsBeginImageContext(self.frame.size)
            self.layer.render(in:UIGraphicsGetCurrentContext()!)
            let image = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return UIImage(cgImage: image!.cgImage!)
        }
      }
    }
    

提交回复
热议问题