tags:

views:

1423

answers:

1

I'm trying to draw some simples lines with the iPhone/Touch SDK. I'd like to be able to change the color of the lines, but calling CGContextSetRGBStrokeColor doesn't seem to affect the drawn lines that are made with CGContextAddLineToPoint until the actual call to CGContextStrokePath is made. So if I make multiple calls to change the color, only the one made just before CGContextStrokePath has any effect. Here's what I mean:

    - (void)drawRect:(CGRect)rect 
{
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextMoveToPoint(ctx, 0, 0);
    CGContextSetRGBStrokeColor(ctx,1,0,0,1);
    CGContextAddLineToPoint(ctx, 100, 100);
    //CGContextStrokePath(ctx);
    CGContextSetRGBStrokeColor(ctx,0,1,0,1);
    CGContextAddLineToPoint(ctx, 200, 300);
    //CGContextStrokePath(ctx);
    CGContextSetRGBStrokeColor(ctx,0,0,1,1);
    CGContextStrokePath(ctx);
}

I assume I'm doing something horribly wrong, I just can't quite figure out what. I thought that if I added the CGContextStrokePath calls, that would help, it doesn't.

See discussion below for how I got to the corrected code:

- (void)drawRect:(CGRect)rect 
{
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextBeginPath(ctx);
    CGContextMoveToPoint(ctx, 0, 0);
    CGContextSetRGBStrokeColor(ctx,1,0,0,1);
    CGContextAddLineToPoint(ctx, 100, 100);
    CGContextStrokePath(ctx);
    CGContextClosePath(ctx);
    CGContextBeginPath(ctx);
    CGContextMoveToPoint(ctx, 100, 100);
    CGContextSetRGBStrokeColor(ctx,0,1,0,1);
    CGContextAddLineToPoint(ctx, 200, 300);
    CGContextStrokePath(ctx);
}
+2  A: 

I don't think you're doing anything horribly wrong, just that CGContextStrokePath for a given Graphics Context can only have one RGBStrokeColor at a time. As a result, multiple calls to CGContextStrokePath are required, once for each colour.

A reference (not a copy) to the Graphics Context is added to that stack of drawing operations with each call to CGContextAddLineToPoint() . When you finally call CGContextStrokePath(), the last value for RGBStrokeColor is used.

If you want to use multiple colours with the same Graphics Context, then it appears that you need to make multiple calls to CGContextStrokePath() changing the value of RGBStrokeColor() on the Graphics Context between calls. The Apple sample code in AccelerometerGraph/GraphView.m appears to indicate this also.

Pierce Hickey
Hm, That is the conclusion I came to as well, but when I run the code above in the simulator with CGContextStrokePath(ctx) lines not commented out, I get the first line drawn in red, and then nothing. What it looks to me like it should do, is draw the first line in red, and then draw the second in green, but if I run it in the iPhone simulator, that isn't what happens.
stinkymatt
Perhaps the current path (including start point) is obliterated when you make the first call? According to the Apple docs - "Quartz uses the line width and stroke color of the graphics state to paint the path. As a side effect when you call this function, Quartz clears the current path."
Pierce Hickey
First, I commend you on your use of the word obliterated. It is one of my favorites.Second, I thank you for helping me see the docs a different way. What must be done is to call CGContextBeginPath(ctx). Then change the stroke color, move the start point, and add the line, then stroke and close thae path. Repeat for subsequent line segments. I'll try to add the corrected code to my original post for posterity. Thanks!
stinkymatt