Silver Challenge Question


#1

For the silver challenge I avoided the need for using CGContextSaveGState and CGContextRestoreGState by creating a second CGContextRef and setting the shadow color to NULL:

//Draw a crosshair CGContextRef ctx2 = UIGraphicsGetCurrentContext(); CGContextSetShadowWithColor(ctx2,offset,0, NULL); [[UIColor greenColor] setStroke]; CGContextSetLineWidth(ctx2,2); CGContextMoveToPoint(ctx2,center.x-10 ,center.y ); CGContextAddLineToPoint(ctx2,center.x +10,center.y); CGContextStrokePath(ctx2); CGContextMoveToPoint(ctx2,center.x ,center.y-10 ); CGContextAddLineToPoint(ctx2,center.x,center.y+10); CGContextStrokePath(ctx2);

Is there something wrong with this approach?

Thanks,
Josh


#2

You haven’t actually created a new graphics context; you have just modified the current graphics context, (permanently maybe, I am not sure.)


#3

You’re right. If I use ctx or ctx2 in the code I get the same results. Either way I get a crosshair without a shadow, so I’m confused now. After a shake event I still have a green crosshair without shadow on top of text with a shadow.


#4

If your program follows what most people are doing, then your program should follow this pattern:

  1. start program
  2. drawRect
    2.a. draw colored concentric circles
    2.b. draw text with shadow
    2.c. draw crosshair without shadow
  3. shake event
  4. drawRect (called due to shake event and the setNeedsDisplay method call in setCircleColor)
    4.a. draw colored concentric circles
    4.b draw text with shadow
    4.c. draw crosshair without shadow

essentially the shake event redraws everything in the same order.


#5

I am also not sure why we need to use CGContextSaveGState(CGContextRef c); and CGContextRestoreGState(CGContextRef c);

I’ve written my crosshairs with and without these functions and it turns out the same. Can anyone explain to my why I would need to use them?

Thanks!
Chantel


#6

Hi guys,

I’m in the same boat.

I did a very similar solution to the first post. Managed to draw a crosshair on the screen, above the text - no problem.

Tomorrow I will research the two extra methods - but right now, I also don’t know why we use them?

When I shake my device, the circles change colour as they should - crosshair remains above the text in green as it should.

What are we missing?


#7

When I did the challenge I saved the graphics state just before I set the shadow using the CGContextSaveGState function and then restored the state after drawing the text using CGContextRestoreGState. This reverted my context’s graphics state to the state it was in before I set the shadow. Your approach was to disable the shadow by setting its color to NULL in the CGContextSetShadowWithColor function. Both solutions provide the same result.

For this example there doesn’t seem to be much benefit for one approach over the other. Where I think CGContextSaveGState and CGContextRestoreGState might come in handy is when you make multiple changes to the graphics state and want to restore back to an earlier version. The documentation for the CGContextSaveGState lists the different graphics state parameters that are saved by this method and there are quite a few.


#8

[quote=“takeiteasybrah”]When I did the challenge I saved the graphics state just before I set the shadow using the CGContextSaveGState function and then restored the state after drawing the text using CGContextRestoreGState. This reverted my context’s graphics state to the state it was in before I set the shadow. Your approach was to disable the shadow by setting its color to NULL in the CGContextSetShadowWithColor function. Both solutions provide the same result.

For this example there doesn’t seem to be much benefit for one approach over the other. Where I think CGContextSaveGState and CGContextRestoreGState might come in handy is when you make multiple changes to the graphics state and want to restore back to an earlier version. The documentation for the CGContextSaveGState lists the different graphics state parameters that are saved by this method and there are quite a few.[/quote]

Thanks for clearing it up for us.

Might revisit this chapter again.


#9

[quote=“takeiteasybrah”]When I did the challenge I saved the graphics state just before I set the shadow using the CGContextSaveGState function and then restored the state after drawing the text using CGContextRestoreGState. This reverted my context’s graphics state to the state it was in before I set the shadow. Your approach was to disable the shadow by setting its color to NULL in the CGContextSetShadowWithColor function. Both solutions provide the same result.

For this example there doesn’t seem to be much benefit for one approach over the other. Where I think CGContextSaveGState and CGContextRestoreGState might come in handy is when you make multiple changes to the graphics state and want to restore back to an earlier version. The documentation for the CGContextSaveGState lists the different graphics state parameters that are saved by this method and there are quite a few.[/quote]
I think this explains it perfectly, and thank you for this answer.

The authors want you to nail down thinking in terms of contexts here. So in your program, you’re going to change the context to add shadows to everything drawn, and write some text. Then, they very clearly tell you after that happens, they want you to do some non-shadowed drawing.

You could just ignore the whole concept of contexts and try and undo what you just did with the shadowing.

But what they doubtless intended for you to do was to realize, “Hey, if I save the context BEFORE I start shadowing and doing all this text stuff, I can bring it right back without worrying about all the changes I just made.”

If you think about it for a minute, NOT saving the context you were working in would be a real PITA if you do some really complicated drawing, and then have to try to undo everything you just did. That’s just a recipe for buggy and tedious programming.