problem to draw and fill rect after cgcontextclip - iphone

I want to clip a rectangle from cgpath with the following code. I don't get any output. What's wrong?
CGContextRef context = UIGraphicsGetCurrentContext();
CGMutablePathRef thePath = CGPathCreateMutable();
CGPathMoveToPoint(thePath,NULL,(self.x1),(self.y1));
CGPathAddLineToPoint(thePath,NULL,(self.x2),(self.y2));
CGPathAddLineToPoint(thePath,NULL,bx2,by2);
CGPathAddLineToPoint(thePath,NULL,bx1,by1);
CGContextAddPath(context, thePath);
CGContextClip(context);
CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0);
CFRelease(thePath);

I noticed that you set the fill color, but did you actually fill the path? e.g.
CGContextFillPath(context);

Do you have a current context? i.e. did you use UIGraphicsBeginImageContext() and UIGraphicsPushContext() before you execute the code shown?

Related

How to get diagram with images as a boarder line in iOS?

I drew rectangle diagram with boarder dotted blue line. I would like to rectangle diagram with same images as a boarder line. That means i want to replace dots with images
My Code:
- (void)drawRect:(CGRect)rect
{
context =UIGraphicsGetCurrentContext();
CGContextSetRGBStrokeColor(context, 0.0, 0.0, 1.0, 1.0);
CGFloat dashPattern[10] = {3.0, 2.0};
CGContextSetLineDash(context, 0, dashPattern, 2);
CGContextSetRGBFillColor(context, 0.0, 1.0, 0.0, 1.0);
CGContextSetLineWidth(context, 10.0);
CGContextAddRect(context, self.bounds);
CGContextDrawPath(context, kCGPathFillStroke);
CGContextClosePath(context);
CGContextStrokePath(context);
}
Can i set image instead of dots? Please give any suggestions to me. Thanks in advance.
I don't try yet, but maybe you can use:
CGContextSetStrokeColorWithColor(context, [UIColor colorWithPatternImage:myImage].CGColor);

Draw line between two different point

I want to draw line between two points. Here is my code. but context memory is 0.
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 2.0);
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGFloat components[] = {0.0, 0.0, 1.0, 1.0};
CGColorRef color = CGColorCreate(colorspace, components);
CGContextSetStrokeColorWithColor(context, color);
CGContextMoveToPoint(context, 0, 0);
CGContextAddLineToPoint(context, 300, 400);
CGContextStrokePath(context);
CGColorSpaceRelease(colorspace);
CGColorRelease(color);
You need to call your code within a UIView subclass in the method drawRect:.
UIGraphicsGetCurrentContext() will get NULL (0) when your are not in a drawing context.
You might also check the docs.
Here is a very useful tutorial for your need.
http://trailsinthesand.com/exploring-iphone-graphics-part-1/
Go through it once..!

How to fill the shapes with color

I am new to Objective-C and iOS development. I have a view with some figures drawn by core drawing. Now I want to fill those shapes with color and I don't know the path or context of shape. Does Objective-C have any function like flood-fill or put-pixel so that by having only the stroke color I can fill any shape inside my view.
-(void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 4.0);
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGFloat components[] = {1.0, 0.0, 0.0, 1.0};
CGColorRef color = CGColorCreate(colorspace, components);
CGContextSetStrokeColorWithColor(context, color);
CGContextMoveToPoint(context, 50, 0);
CGContextAddLineToPoint(context, 0,320);
CGContextStrokePath(context);
CGColorSpaceRelease(colorspace);
CGColorRelease(color);
CGContextSetLineWidth(context, 2.0);
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGContextSetRGBFillColor(context, 0, 255, 0, 1.0);
CGContextMoveToPoint(context, 100, 100);
CGContextAddLineToPoint(context, 150, 150);
CGContextAddLineToPoint(context, 100, 200);
CGContextAddLineToPoint(context, 50, 150);
CGContextAddLineToPoint(context, 100, 100);
CGContextStrokePath(context);
CGContextSetLineWidth(context, 2.0);
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGRect rectangle = CGRectMake(60,170,200,80);
CGContextAddEllipseInRect(context, rectangle);
CGContextStrokePath(context);
}
This will make a circle and a square with some common region. I want a particular region to fill with color when a user taps that region.
So you are looking for flood fill in Objective C.
This is my implementation of Scan Line Flood Fill Algorithm.
Github : UIImageScanlineFloodfill
If you want to learn basic of flood fill:
Lode's Computer Graphics Tutorial Flood Fill
I hope this will help you.
Put your drawing code in the question and I can give you a specific answer.
Normally you just need to set a fill color using
[[UIColor redColor] setFill];
And any shapes you draw your core graphics will be filled with that color automatically.
Try this command:-
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
Core Graphics is closely tied to UIView and its drawRect: method and has a C interface. As you point out, you always draw in the current graphics context. I can think of 2 approaches: (1) When the user taps myView, set a property like myView.pointTapped, and in drawRect: find the shape to fill, set a fill color, and fill the closed path using GGGeometry methods.
There is an objective-C alternative: (2) Take a look at UIBezierPath. It's not as comprehensive as drawing in Core Graphics but it can be used in your ViewController implementation.

Shadow at the top of a Cell UITableCellView

I wondered if anyone knows how to get a shadaow effect like the one in things as per the screenshot. To me it looks like the shadow effect is created by having a shadow at the bottom of the cell above and the top of the cell below.
I can create the one from the cell above using the code below but can't figure out how to do it on the cell underneath as it doesn't get shown it's as if the cells are rendered in reverse order in terms of the z-index.
self.layer.shadowOffset = CGSizeMake(0, 2);
self.layer.shadowColor = [[UIColor blackColor] CGColor];
self.layer.shadowRadius = 2;
self.layer.shadowOpacity = 0.5;
CGFloat top = self.layer.bounds.origin.y;
CGFloat left = self.layer.bounds.origin.x;
CGFloat width = self.layer.bounds.size.width;
CGRect shadowFrame = CGRectMake(left, top, width, 44);
CGPathRef shadowPath = [UIBezierPath bezierPathWithRect:shadowFrame].CGPath;
self.layer.shadowPath = shadowPath;
Any suggestions much appreciated.
Things http://www.purplesmash.com/images/Things.jpg
Just create hollow rectangle while drawing with CoreGraphics (align it exactly that hollow part cover your cell visible view) and set shadow for context - this will save performance for you.
UPDATE:
I've tried this inside my cell drawRect: method
// Creating path which will hold our hollow rectangle
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, CGRectMake(-8.0f, -8.0f, 336.0f, 96.0f));
CGPathAddRect(path, NULL, CGRectMake(-5.0f, 0.0f, 330.0f, 80.0f));
// Saving current graphics context state
CGContextSaveGState(context);
// Configuring shadow
CGContextSetShadowWithColor(context, CGSizeMake(0.0f, 0.0f), 6.0f,
[[UIColor blackColor] CGColor]);
// Adding our path
CGContextAddPath(context, path);
// Configure hollow rectangle fill color
CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0);
// Fill rectangle and keep hollow part transparent
CGContextEOFillPath(context);
// Restore graphics context
CGContextRestoreGState(context);
Of course additional improvement will be pre-calculate CGMutablePathRef path somewhere in initialization or in this method by condition if(path == NULL). Colors can be retained too. If this should be last row of your cell update, than maybe you don't event need to save context state.
You probably need to do this by drawing the shadows as part of the checked cell instead of setting the shadow properties on the surrounding cells.
I'd do it by adding one or two CAGradientLayers as children of the checked cell's contentView.layer.
I have edited this in light of the suggestion from moonlight. I put that code into a method addInnerTopShadow when a cell needs that I call the method. I have added another method addInnerBottomShadow which puts in the shadow at the bottom.
I call these methods in the drawRect method and when I want to change between the states I call the method:
[cell setNeedsDisplay];
This allows me to toggle the state of the cell without doing things like
[self.tableView reloadData];
As the methods suggest I have outer shadow methods that put a shadow on the first and last cells but that's another issue and has been answered many times. I now have my app working exactly how I want. So thanks to Rob and Moonlight.
-(void)addInnerBottomShadow
{
CGContextRef context = UIGraphicsGetCurrentContext();
// Creating path which will hold our hollow rectangle
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, CGRectMake(0, 44, 480, 80));
CGPathAddRect(path, NULL, CGRectMake(0, 54, 480, 96));
// Saving current graphics context state
CGContextSaveGState(context);
// Configuring shadow
CGContextSetShadowWithColor(context, CGSizeMake(0.0f, 0.0f), 6.0f, [[UIColor blackColor] CGColor]);
// Adding our path
CGContextAddPath(context, path);
// Configure hollow rectangle fill color
CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0);
// Fill rectangle and keep hollow part transparent
CGContextEOFillPath(context);
CGContextClipToRect(context, self.bounds);
// Restore graphics context
CGContextRestoreGState(context);
}
-(void)addInnerTopShadow
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, CGRectMake(-8.0f, -8.0f, 336.0f, 96.0f));
CGPathAddRect(path, NULL, CGRectMake(-5.0f, 0.0f, 330.0f, 80.0f));
// Saving current graphics context state
CGContextSaveGState(context);
// Configuring shadow
CGContextSetShadowWithColor(context, CGSizeMake(0.0f, 0.0f), 7.0f, [[UIColor blackColor] CGColor]);
// Adding our path
CGContextAddPath(context, path);
// Configure hollow rectangle fill color
CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0);
// Fill rectangle and keep hollow part transparent
CGContextEOFillPath(context);
CGContextClipToRect(context, self.bounds);
// Restore graphics context
CGContextRestoreGState(context);
}

Export CGPath as JPG or PNG

Is it possible to take a path draw in an UIView with CGPath and export it as a PNG?
Assuming you want a UIImage, not a png file, you can do something like this:
UIGraphicsBeginImageContext(size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0);
CGContextSetLineWidth(context, 2.0);
CGContextSetLineCap(context, kCGLineCapSquare);
//DRAW YOUR PATH HERE
CGContextStrokePath(context);
myUIImage = UIGraphicsGetImageFromCurrentImageContext();
[myUIImage retain];
UIGraphicsEndImageContext();
The cleanest way to do that is to perform the whole drawing again in an image context produced by UIGraphicsBeginImageContext(), get an UIImage out of it, then save it via the UIImagePNG/JPEGRepresentation() functions.
Note that UIView do not "hold" images. You can rerender a UIView's layer, but it's a gross violation of MVC (you're using views to store model data!), and it doesn't look clean to me.