Search code examples
iosswiftcore-graphics

How to draw dashed arrow?


I want to draw arrow like this:

enter image description here

I found how to draw just solid arrow here, but i don't know how to draw arrow like above.

Solution:

For me I ended up with code below:

func addArrowOntoView(view: UIView, startPoint: CGPoint, endPoint: CGPoint, color: UIColor) {
    let line = UIBezierPath()
    line.moveToPoint(startPoint)
    line.addLineToPoint(endPoint)

    let arrow = UIBezierPath()

    arrow.moveToPoint(endPoint)
    arrow.addLineToPoint(CGPointMake(endPoint.x - 5, endPoint.y - 4))
    arrow.moveToPoint(endPoint)
    arrow.addLineToPoint(CGPointMake(endPoint.x - 5, endPoint.y + 4))
    arrow.lineCapStyle = .Square

    let sublayer = CAShapeLayer()
    sublayer.path = line.CGPath
    view.layer.addSublayer(sublayer)

    //add Line
    let lineLayer = CAShapeLayer()
    lineLayer.path = line.CGPath
    lineLayer.strokeColor = color.CGColor
    lineLayer.lineWidth = 1.0
    lineLayer.lineDashPattern = [5, 3]
    view.layer.addSublayer(lineLayer)

    //add Arrow
    let arrowLayer = CAShapeLayer()
    arrowLayer.path = arrow.CGPath
    arrowLayer.strokeColor = color.CGColor
    arrowLayer.lineWidth = 1.0
    view.layer.addSublayer(arrowLayer)
}

Solution

  • Here is a code for such an ArrowView that I wrote to get this in a playground:

    //ArrowView

    class ArrowView : UIView {
    
    
    var dashWidth :CGFloat = 3.0
    var dashGap : CGFloat = 3.0
    var arrowThickNess : CGFloat = 2.0
    var arrowLocationX : CGFloat = 0.0
    //MARK:
    
    override func drawRect(rect: CGRect) {
    
        //Compute the dashPath 
    
        let path = UIBezierPath()
    
        //Compute the mid y, path height
        let midY = CGRectGetMidY(frame)
        let pathHeight = CGRectGetHeight(frame)
    
    
        path.moveToPoint(CGPointMake(frame.origin.x, midY))
        path.addLineToPoint(CGPointMake(frame.origin.x + frame.size.width - dashWidth , midY))
        path.lineWidth = arrowThickNess
    
        let dashes: [CGFloat] = [dashWidth, dashGap]
        path.setLineDash(dashes, count: dashes.count, phase: 0)
    
    
        //Arrow 
    
        let arrow = UIBezierPath()
    
        arrow.lineWidth = arrowThickNess
    
        arrow.moveToPoint(CGPointMake(frame.origin.x + arrowLocationX , midY))
        arrow.addLineToPoint(CGPointMake(frame.origin.x + frame.size.width -  arrowThickNess/2 - 18, 0))
        arrow.moveToPoint(CGPointMake(frame.origin.x + arrowLocationX , midY))
        arrow.addLineToPoint(CGPointMake(frame.origin.x + frame.size.width - arrowThickNess/2 - 18 , pathHeight))
        arrow.lineCapStyle = .Square
    
    
        UIColor.whiteColor().set()
        path.stroke()
        arrow.stroke()
    
     }
    
    }
    
    
    let arrowView = ArrowView(frame: CGRect(x: 0, y: 0, width: 210, height: 20))
    arrowView.dashGap = 10
    arrowView.dashWidth = 5
    arrowView.arrowLocationX = 202
    
    arrowView.setNeedsDisplay()
    

    Basically you will need to create a bezier path with required line dashes and you will need to supply the dashes as an array of float values. At the end of this bezier path, you will need to draw another bezier path representing the arrow.

    Output:-

    enter image description here