Search code examples
iosswiftuibezierpath

Is it possible to show/stroke only a portion of a UIBezierPath?


I have a UIBezierPath shape (comprised of various line segments) already defined, but depending on the scenario, I only want certain portions of it visible. Is this possible?

I was initially thinking along the lines of how when you animate a UIBezierPath, you can animate from a .fromValue to a .toValue. Can I set some sort of "current value" (which I see exists, but only as a getOnly property) to accomplish something similar, outside of an animation context?

Another way I thought of was to just treat my path as a sort of "template" path, and then break it up into various subpaths, but I'm hoping there is an easier/more direct way (unless this method is easier than I anticipate...).


Solution

  • UIBezierPath doesn't have that, but if you add the path to a CAShapeLayer, you can control the strokeStart and strokeEnd.

    Try this in a playground:

    let path = UIBezierPath()
    path.move(to: .zero)
    path.addLine(to: CGPoint(x: 10, y: 10))
    path.addLine(to: CGPoint(x: 20, y: 0))
    path.addLine(to: CGPoint(x: 30, y: 10))
    let layer = CAShapeLayer()
    layer.path = path.cgPath
    layer.strokeColor = UIColor.red.cgColor
    layer.fillColor = UIColor.clear.cgColor
    
    // Note these lines
    layer.strokeStart = 0.2 // start at 20% of the way
    layer.strokeEnd = 0.8 // end at 80% of the way
    
    layer.lineWidth = 2
    let view = UIView(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
    view.layer.addSublayer(layer)
    

    The above produces:

    enter image description here

    Without the two lines that set the stroke start and end, the view looks like:

    enter image description here