CoreGraphics Multi-Colored Line - iphone

I have the following code the only seems to use the last colour for the whole line.....
I want the colour to be changing throughout this. Any ideas?
CGContextSetLineWidth(ctx, 1.0);
for(int idx = 0; idx < routeGrabInstance.points.count; idx++)
{
CLLocation* location = [routeGrabInstance.points objectAtIndex:idx];
CGPoint point = [mapView convertCoordinate:location.coordinate toPointToView:self.mapView];
if(idx == 0)
{
// move to the first point
UIColor *tempColor = [self colorForHex:[[routeGrabInstance.pointHeights objectAtIndex:idx] doubleValue]];
CGContextSetStrokeColorWithColor(ctx,tempColor.CGColor);
CGContextMoveToPoint(ctx, point.x, point.y);
}
else
{
UIColor *tempColor = [self colorForHex:[[routeGrabInstance.pointHeights objectAtIndex:idx] doubleValue]];
CGContextSetStrokeColorWithColor(ctx,tempColor.CGColor);
CGContextAddLineToPoint(ctx, point.x, point.y);
}
}
CGContextStrokePath(ctx);

The CGContextSetStrokeColorWithColor only changes the state of the context, it does not do any drawing. The only drawing done in your code is by the CGContextStrokePath at the end. Since each call to CGContextSetStrokeColorWithColor overrides the value set by the previous call the drawing will use the last color set.
You need to create a new path, set the color and then draw in each loop. Something like this:
for(int idx = 0; idx < routeGrabInstance.points.count; idx++)
{
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, x1, y1);
CGContextAddLineToPoint(ctx, x2, y2);
CGContextSetStrokeColorWithColor(ctx,tempColor.CGColor);
CGContextStrokePath(ctx);
}

CGContextSetStrokeColorWithColor sets the stroke color in the context. That color is used when you stroke the path, it has no effect as you continue building the path.
You need to stroke each line separately (CGContextStrokePath).

Related

Draw line with border iPhone using CGContext

I want to draw line with border,
right now i am doing same thing twice, means first i draw line with stroke +3 and again draw line with normal stroke like 1,
so i do run loop twice for it,
is there any other way for better performance? or any anthor way to draw two line simultaniously.??
My code is
if (locations && ([locations length]/16 > 1)) {
CGPoint point;
polylinewidth=10;
CGContextSetLineWidth(context, polylinewidth);
CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);
for (int i = 0; i <= locations.length - 32; i += 32) {
NSAutoreleasePool *loc = [[NSAutoreleasePool alloc]init];
CLLocationCoordinate2D coordinates;
coordinates.latitude = hexDecode_iPhone([locations substringWithRange:NSMakeRange(i, 16)]);
coordinates.longitude = hexDecode_iPhone([locations substringWithRange:NSMakeRange(i+16, 16)]);
point = [mapView convertCoordinate:coordinates toPointToView:self.mapView];
if (i == 0)
CGContextMoveToPoint(context, point.x, point.y);
else
CGContextAddLineToPoint(context, point.x, point.y);
[loc drain];
}
CGContextStrokePath(context);
CGContextSetLineWidth(context, polylinewidth-5);
CGContextSetAlpha(context, 0.6);
CGContextSetStrokeColorWithColor(context, color.CGColor);
for (int i = 0; i <= locations.length - 32; i += 32) {
NSAutoreleasePool *loc = [[NSAutoreleasePool alloc]init];
CLLocationCoordinate2D coordinates;
coordinates.latitude = hexDecode_iPhone([locations substringWithRange:NSMakeRange(i, 16)]);
coordinates.longitude = hexDecode_iPhone([locations substringWithRange:NSMakeRange(i+16, 16)]);
point = [mapView convertCoordinate:coordinates toPointToView:self.mapView];
if (i == 0)
CGContextMoveToPoint(context, point.x, point.y);
else
CGContextAddLineToPoint(context, point.x, point.y);
[loc drain];
}
CGContextStrokePath(context);
}
Thanks.

Is it possible to draw anyhitng on MPMoviePlayerController

IS it possible to add an points on line in MPMovieplayercontroller..
If yes then how..Becoz as it is possible to draw the line on view .then MPMovieplayerconteoler is also an view only..
- (void)drawSquiggle:(Squiggle *)squiggle inContext:(CGContextRef)context
{
// set the drawing color to the squiggle's color
UIColor *squiggleColor = squiggle.strokeColor; // get squiggle's color
CGColorRef colorRef = [squiggleColor CGColor]; // get the CGColor
CGContextSetStrokeColorWithColor(context, colorRef);
// set the line width to the squiggle's line width
CGContextSetLineWidth(context, squiggle.lineWidth);
NSMutableArray *points = [squiggle points]; // get points from squiggle
// retrieve the NSValue object and store the value in firstPoint
CGPoint firstPoint; // declare a CGPoint
[[points objectAtIndex:0] getValue:&firstPoint];
// move to the point
CGContextMoveToPoint(context, firstPoint.x, firstPoint.y);
// draw a line from each point to the next in order
for (int i = 1; i < [points count]; i++)
{
NSValue *value = [points objectAtIndex:i]; // get the next value
CGPoint point; // declare a new point
[value getValue:&point]; // store the value in point
// draw a line to the new point
CGContextAddLineToPoint(context, point.x, point.y);
} // end for
CGContextStrokePath(context);
} // end method drawSquiggle:inContext:
end method touchesBegan:withEvent:
This is the code which i had used..
mpPlayer is the mpvideoplayer object
but it is not able to draw point on mpvideoplayer..
Is there any way out.Please help me..
There is an example in the IOS SDK that has an overlay view over a playing movie. That should be a good start.
https://developer.apple.com/library/ios/#samplecode/MoviePlayer_iPhone/Introduction/Intro.html

Core Graphics drawing only black

I'm trying to develop a chess game on the iPhone, and have become stuck on an otherwise insignificant detail but can not seem to get past it. Can anybody see the piece that's missing?
Here's the problem. When a user clicks on a square, it should highlight in some faded color. What actually is happening though, is it just draws black, totally regardless of what color I set it to.
Here's an image of what I get. The black circle should be red, or any color.
Here, notice the UIView I'm drawing to is behind the pieces view. Doubt it matters, but I want to be complete.
Finally, the code for the layer:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.backgroundColor = [UIColor clearColor];
rowSelected = 0;
colSelected = 0;
}
return self;
}
-(void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClearRect(context, rect);
CGContextSetRGBStrokeColor(context, 255.0, 0.0, 0.0, 1.0);
if (rowSelected && colSelected)
{
int gridsize = (self.frame.size.width / 8);
int sx = (colSelected-1) * gridsize;
int sy = (rowSelected-1) * gridsize;
int ex = gridsize;
int ey = gridsize;
CGContextFillEllipseInRect(context, CGRectMake(sx,sy,ex,ey));
}
}
// Handles the start of a touch
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
int gridsize = (self.frame.size.width / 8);
// Position of touch in view
UITouch *touch = [[event allTouches] anyObject];
CGPoint loc = [touch locationInView:self.superview];
int x = loc.x / gridsize;
int y = loc.y / gridsize;
rowSelected = y + 1;
colSelected = x + 1;
[self setNeedsDisplay];
}
I have tried a number of things, using a value of 1 rather than 255, playing with the alpha, etc, but I can't get anything other than a solid black.
EDIT:
Also, here's the code of this view's superview:
#implementation ChessBoard
-(id)initWithFrame:(CGRect)frame
{
if (self != [super initWithFrame:frame])
return self;
int SQUARE_SIZE = frame.size.width / 8;
currentSet = BW;
UIImage *img = [UIImage imageNamed:#"board.png"];
background = [[UIImageView alloc] initWithImage:img];
[background setFrame:frame];
[self addSubview:background];
overlay = [[ChessBoardOverlay alloc] initWithFrame:frame];
[self addSubview:overlay];
In the function CGContextSetRGBStrokeColor color compontent values (red, green,blue, alpha) need to be between 0 and 1. Since you are assuming that 255 is the maximum for a color you need to divide all of your color component values by 255.0f.
CGContextSetRGBStrokeColor(context, 255.0f/255.0f, 0.0/255.0f, 0.0/255.0f, 1.0);
You say you're drawing to a layer... but a CALayer doesn't have a drawRect: method, it has drawInContext:
I would guess by trying to call drawRect: in your instance of a CALayer that the true context hasn't been built correctly, or it has but you're not tying in to it.
Maybe you should state your color this way:
CGContextSetRGBStrokeColor(context, 255.0/255.0f, 0.0/255.0f, 0.0/255.0f, 1.0f);
This happened to me once using:
[UIColor colorWithRed:12.0/255.0f green:78.0/255.0f blue:149.0/255.0f alpha:1.0f];
until I added the /255.0f so that may work.

drawRect not responding

I am trying to draw a pentagon with a set of points storing in a NSArrary, however, the view is empty without any error...
-(void)prepareVertex:(int)noOfVertex
{
polygonPoint=[NSMutableArray arrayWithCapacity:noOfVertex];
for(int i=0;i<noOfVertex;i++)
{
CGPoint point=CGPointMake(sin((2*M_PI)*i/noOfVertex),(cos(2*M_PI)*i/noOfVertex));
[polygonPoint addObject:[NSValue valueWithCGPoint:point]];
NSValue *tempVal=[polygonPoint objectAtIndex:i];
CGPoint tempPoint=[tempVal CGPointValue];
NSLog(#"%f,%f",tempPoint.x,tempPoint.y);
}
}
- (void)drawRect:(CGRect)rect
{
[self prepareVertex:5];
for (int i=0; i<5; i++) {
NSValue *tempVal=[polygonPoint objectAtIndex:i];
CGPoint tempPoint=[tempVal CGPointValue];
}
CGContextRef context=UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 5);
CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor);
CGContextMoveToPoint(context, [[polygonPoint objectAtIndex:0] CGPointValue].x, [[polygonPoint objectAtIndex:0] CGPointValue].x);
for (int i=1; i<5; i++) {
CGPoint point=[[polygonPoint objectAtIndex:i] CGPointValue];
CGContextAddLineToPoint(context,point.x, point.y);
}
CGContextStrokePath(context);
}
Can anyone tell me whats going on??
Well, the first think to note is that you use black to stroke the polygon, so if your view background is black too, you can't see any thing.
Then, and I think this is the real problem, sin(x) and cos(x) are always between -1 and 1, so the points you generate in:
CGPoint point=CGPointMake(sin((2*M_PI)*i/noOfVertex),(cos(2*M_PI)*i/noOfVertex));
are all located in the rectangle CGrectMake(-1, -1, 2, 2). And that area of your view is very probably hidden by the status bar.
So, if the coordinates you generated are what you are looking for are correct, you may try to remove the status bar or change the coordinates of your view. But I think What you should really do is change the previous line into something like this:
CGFloat x = centerPoint.x + radius * sin(2*M_PI*i/noOfVertex);
CGFloat y = centerPoint.y + radius * cos(2*M_PI*i/noOfVertex);
CGPoint point = CGPointMake(x, y);
It draws something in the upper left corner of the view. The figure is just too small to see easily. That's because the values in polygonPoint (btw you should at least call the array polygonPoints) are between -1.0 and 1.0. You have to translate your points to the center of the view and scale the size accordingly.
Something like
- (void)drawRect:(CGRect)rect {
[self prepareVertex:5];
CGContextRef context=UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 5);
CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor);
CGFloat x = self.center.x + self.bounds.size.width * 0.5 * [[polygonPoint objectAtIndex:0] CGPointValue].x;
CGFloat y = self.center.y + self.bounds.size.height * 0.5 * [[polygonPoint objectAtIndex:0] CGPointValue].y;
NSLog(#"Point %f/%f", x, y);
CGContextMoveToPoint(context, x, y);
for (int i=1; i<5; i++) {
CGPoint point=[[polygonPoint objectAtIndex:i] CGPointValue];
x = self.center.x + self.bounds.size.width * 0.5 * point.x;
y = self.center.y + self.bounds.size.height * 0.5 * point.y;
NSLog(#"Point %f/%f", x, y);
CGContextAddLineToPoint(context, x, y);
};
CGContextStrokePath(context);
}
does the trick.

CoreGraphics: Using finger strokes to erase part of image?

I'm working on drawing code to erase part of an image. I'm not an expert on CoreGraphics and could use some help.
This routine works fine, however, when moving fast, it loses touches (Not very smooth). Can this routine be modified to make CGContextClearRect smoother? Is there a better, faster way to do this?
-(void)drawRect:(CGRect)rect {
if (!myDrawing) { // touchpoints stored here
myDrawing = [[NSMutableArray alloc] initWithCapacity:0];
}
UIGraphicsBeginImageContext(frontImage.frame.size);
[frontImage.image drawInRect:CGRectMake(0, 0, frontImage.frame.size.width, frontImage.frame.size.height)];
if ([myDrawing count] > 0) {
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 5);
CGContextSetLineCap(UIGraphicsGetCurrentContext(),kCGImageAlphaNone );
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1, 0, 0, 10);
for (int i = 0 ; i < [myDrawing count] ; i++) {
NSArray *thisArray = [myDrawing objectAtIndex:i];
if ([thisArray count] > 2) {
float thisX = [[thisArray objectAtIndex:0] floatValue];
float thisY = [[thisArray objectAtIndex:1] floatValue];
CGContextBeginPath(UIGraphicsGetCurrentContext());
for (int j = 2; j < [thisArray count] ; j+=2) {
thisX = [[thisArray objectAtIndex:j] floatValue];
thisY = [[thisArray objectAtIndex:j+1] floatValue];
CGContextClearRect (UIGraphicsGetCurrentContext(), CGRectMake(thisX, thisY, 10, 10));
}
}
}
}
frontImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
You don't have to use CGContextClearRect to clear strokes.
Instead do CGContextSetBlendMode(context, kCGBlendModeClear)
This call changes the color blending mode in such a way that drawing operations would be clearing bitmap instead of drawing with color.
Then you can just draw lines which connect touch locations so that there are no gaps.
To switch back to normal rendering do CGContextSetBlendMode(context, kCGBlendModeNormal)
Using different blending modes can be very helpful.
You should never do anything but drawing in your drawRect code. That really slows down the process. Instead, think of perhaps splitting off rendering to a separate thread. That will really speed things up.