Question

So, I need to draw a series of dotted lines along an axis. In the drawRect method I call another method to draw the axis.. In that method I save the GState draw the axis and then save the gstate again draw the dotted line when appropriate,then stroke the path restore the gstate add some thing to the axis fill the path.. The thing is now the whole thing is dotted ... It seems the the code didn't discard the dotted line pattern when I restored the gstate ...

   CGContextSaveGState(ctx);
    CGContextSetFillColorWithColor(ctx, [[UIColor whiteColor] CGColor]);
 .......
    //draw a dased line
            CGContextSaveGState(ctx);
            CGContextSetLineWidth(ctx, 1.0);
            CGContextSetStrokeColorWithColor(ctx, [UIColor whiteColor].CGColor);
            CGFloat const kDashedLinesLength[]   = {1.0f, 0.5f};
            CGContextSetLineDash(ctx, 0.0, kDashedLinesLength, 2);
            CGContextMoveToPoint(ctx, LEFT_EXCLUSION_LENGTH + AXIS_LINE_WIDTH, crtYval);
            CGContextAddLineToPoint(ctx, LEFT_EXCLUSION_LENGTH + AXIS_LINE_WIDTH + self.xAxis.visibleLength , crtYval);
            CGContextStrokePath(ctx);
            CGContextRestoreGState(ctx);
...
   CGContextFillPath(ctx);
    CGContextRestoreGState(ctx);

How can I make sore that only the line I need gets doted ???

Was it helpful?

Solution

I'm not sure what's wrong with your code, but it's not a bug in the context restore which works fine. Likely you have another error in the code you replaced with .....

Could be that you have unbalanced save and restores which will cause all kinds of problems - I'd check that first.

I copied and pasted it with minimal changes into a small iOS test app custom view's drawRect method and ran it and I'm seeing what I expect.

here's the little test code that works as expected:

- (void)drawRect:(CGRect)rect
{
    // Drawing code

    CGContextRef ctx = UIGraphicsGetCurrentContext();

    CGContextSaveGState(ctx);
    CGContextSetFillColorWithColor(ctx, [[UIColor blackColor] CGColor]);
    CGContextSetStrokeColorWithColor(ctx, [UIColor blackColor].CGColor);
    CGContextSetLineWidth(ctx, 2.0);

    //draw a dased line
    CGContextSaveGState(ctx);
    CGContextSetStrokeColorWithColor(ctx, [UIColor blueColor].CGColor);
    CGFloat const kDashedLinesLength[]   = {1.0f, 2.0f};
    CGContextSetLineDash(ctx, 0.0, kDashedLinesLength, 2);
    CGContextMoveToPoint(ctx, 100, 100 );
    CGContextAddLineToPoint(ctx, 100, 200);
    CGContextStrokePath(ctx);
    CGContextRestoreGState(ctx);


    CGContextMoveToPoint(ctx, 200, 100 );
    CGContextAddLineToPoint(ctx, 200, 200);
    CGContextStrokePath(ctx);

    CGContextFillPath(ctx);
    CGContextRestoreGState(ctx);
}

And is the sample output:

screenshot

OTHER TIPS

You need to be careful to always exactly balance a Save with a Restore. I've had situations where I had one or the other too many in a totally different location of my app. Because iOS partially reuses contexts this can leave a graphics context in a weird state.

You should search your source code for all instances of a Save and a Restore and count if there are equal numbers of them.

I think I know your problem. Look at it this way: The line isn't drawn until you stroke the path. So whatever pattern is in effect when you call CGContextAddLineToPoint (for example) doesn't matter. When you call CGContextAddLineToPoint you're not drawing a line, you are simply building a path. I'm guessing that your subroutine for drawing the axes does not stroke them. The axes don't get drawn until you later call CGContextStrokePath, at which point the dashed pattern is in effect.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top