How to draw UIBezierPath identical to MKPolyline in a UIView

后端 未结 2 934
情话喂你
情话喂你 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:36

    Your extensions work fine. The problem may be in the code that adds the layer to the view (which you do not show).

    I'd suggest that you simplify your project, for example use predefined array of points that definitely fit to your view. For example, for a view that is 500 pixels wide and 300 pixels high, you could use something like:

    let points = [
        CGPoint(x: 10, y: 10),
        CGPoint(x: 490, y: 10),
        CGPoint(x: 490, y: 290),
        CGPoint(x: 10, y: 290),
        CGPoint(x: 10, y: 10)
    ]
    

    Use colors that are clearly visible, like black and yellow for your stroke and fill.

    Make sure that your path is correctly added to the view, for example:

    let path = UIBezierPath(points: points)
    
    let shapeLayer = CAShapeLayer(path: path, lineColor: UIColor.blue, fillColor: UIColor.lightGray)
    
    view.layer.addSublayer(shapeLayer)
    

    Inspect the controller that contains the view in Xcode's Interface Builder. In the debug view hierarchy function:

    0 讨论(0)
  • 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!)
        }
      }
    }
    
    0 讨论(0)
提交回复
热议问题