Search code examples
iphoneiosdoublelines

How to draw a double dashed line in Quartz


I am trying to create an app that allows the user to draw a dotted line with their finger on an iPad. I have all of the drawing routines to create single lines. My question is how should I go about drawing a double line in such a way that it will not overlap itself when you create curves. I have been trying to accomplish this by Adding a second line to my Path with an offset of the x and y of the current point. This works fine as long as you move vertically or horizontally. When you draw at an angle, the double lines become a single line.

I am keeping an array of points stored as NSValues (pathPoints) so that I can store them for later use. Starting point is the first point in pathPoints.

    UIGraphicsBeginImageContext(self.frame.size);

    //This needs to be a dotted line
    CGFloat pattern[] = {10,20};
    CGContextSetLineDash(UIGraphicsGetCurrentContext(), 3, pattern, 2);


    CGMutablePathRef path = CGPathCreateMutable();
    CGMutablePathRef path2 = CGPathCreateMutable();


    CGPoint startingPoint = [[pathPoints objectAtIndex:0] CGPointValue];

    CGPathMoveToPoint(path, nil, startingPoint.x, startingPoint.y);
    CGPathMoveToPoint(path2, nil, startingPoint.x + 10, startingPoint.y + 10);

     for (int i = 1; i < [pathPoints count]; i++)
    {
        CGPoint linePoint = [[pathPoints objectAtIndex:i] CGPointValue];
        CGPathAddLineToPoint(path, nil, linePoint.x, linePoint.y);
        CGPathAddLineToPoint(path2, nil, linePoint.x + 10, linePoint.y + 10);

     }

// of course later on I add the paths to the context and stroke them.

        CGContextAddPath(UIGraphicsGetCurrentContext(), path);
        CGContextAddPath(UIGraphicsGetCurrentContext(), path2);

        CGContextStrokePath(UIGraphicsGetCurrentContext());

        UIGraphicsEndImageContext();

I greatly appreciate any help I can get with this.


Solution

  • If you're okay with the lines being joined at the end (see image below) then you can create the effect using CGContextReplacePathWithStrokedPath().

    /**
     * CGContextRef context = <the context you're drawing to>
     * CGFloat lineWidth = <the width of each of your two lines>
     * CGFloat lineSpace = <the space between the two lines>
     **/
    
    // Create your path here (same as you would for a single line)
    
    CGContextSetLineWidth(context, lineWidth + lineSpace);
    CGContextReplacePathWithStrokedPath(context);
    CGContextSetLineWidth(context, lineWidth);
    CGContextStrokePath(context);
    

    Stroked Path