Trying to use CGContextAddArc... nothing is drawn? - objective-c

I am trying to draw an arc. But nothing is drawn?
- (void)viewDidLoad {
[super viewDidLoad];
CGRect rect = CGRectMake(0,0,340,480);
UIView *ui = [[UIView alloc] initWithFrame:rect];
[self.view addSubview:ui];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextAddArc(context, 50, 50, 20, 0, 30, 0);
}

When -viewDidLoad is sent, the current graphics context could be anything. Do your drawing in -drawRect:.

You have to stroke or fill the arc before its visible. You've got a path on screen but you have to stroke or fill it before draws visibly. Use these to do that..
//set the fill or stroke color
CGContextSetRGBFillColor(context, 0.5, 0.5, 0.5, 1.0);
CGContextSetRGBStrokeColor(context, 0.5, 0.5, 0.5, 1.0);
//fill or draw the path
CGContextDrawPath(context, kCGPathStroke);
CGContextDrawPath(context, kCGPathFill);

Related

How to set the Radius Corners to View using DrawRect Method?

using DrawRect method to draw a rectangle view. I have to set the radius corners of that particular rectangle view.I have written to draw a rectangle view below.
- (void)drawRect:(CGRect)rect {
int coordinate_x=60,coordinate_y=120,width=200,height=295;
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect drawTank = {coordinate_x, coordinate_y, width, height};
CGColorRef blackColor=[UIColor blackColor].CGColor;
CGContextSetRGBStrokeColor(context, 0, 0, 255, 1);
CGContextSetLineWidth(context, 1.0);
CGContextSetStrokeColorWithColor(context, blackColor);
CGContextStrokeRect(context, drawTank);
}
And i have to use fill the view and empty view use code below.
CGRect emptyTank = CGRectMake(coordinate_x, coordinate_y, width, height *(1-filledPercentage));
CGRect fullTank = CGRectMake(coordinate_x, coordinate_y+height *(1-filledPercentage),width, height * filledPercentage);
how to set the radius corner to the particular view. please help me.
Thanks in Advance.
you can simply set the corner radius of a UIView with:
view.layer.cornerRadius = 5;
If you are using beizer path , you can set corner radius with the following code:
UIBezierPath* rectanglePath = [UIBezierPath bezierPathWithRoundedRect: CGRectMake(55, 30, 133, 51) cornerRadius: 5];
[UIColor.grayColor setFill];
[rectanglePath fill];
within the drawRect method:
- (void)drawRect: (CGRect)frame
{
//// Rectangle Drawing
UIBezierPath* rectanglePath = [UIBezierPath bezierPathWithRoundedRect: CGRectMake(CGRectGetMinX(frame) + 40, CGRectGetMinY(frame) + 21, 133, 51) cornerRadius: 7];
[UIColor.grayColor setFill];
[rectanglePath fill];
}

Invert colors of image with transparent background

I have an uiimage with transparent background. if I invert the colors with the follow method, the transparent background change to white and then to black.
I want that it doesnt invert transparent pixels? how can i do that?
- (UIImage *) getImageWithInvertedPixelsOfImage:(UIImage *)image {
UIGraphicsBeginImageContextWithOptions(image.size, NO, 2);
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeCopy);
[image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeDifference);
CGContextSetFillColorWithColor(UIGraphicsGetCurrentContext(),[UIColor whiteColor].CGColor);
CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, image.size.width, image.size.height));
UIImage * result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return result;
}
this is how I solved.
It is the code that you can find in other answers, but with the masking of the current image with the same image, with rotated context (for transforming from CG* coords to UI* coords).
- (UIImage *)invertImage:(UIImage *)originalImage
{
UIGraphicsBeginImageContext(originalImage.size);
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeCopy);
CGRect imageRect = CGRectMake(0, 0, originalImage.size.width, originalImage.size.height);
[originalImage drawInRect:imageRect];
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeDifference);
// translate/flip the graphics context (for transforming from CG* coords to UI* coords
CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0, originalImage.size.height);
CGContextScaleCTM(UIGraphicsGetCurrentContext(), 1.0, -1.0);
//mask the image
CGContextClipToMask(UIGraphicsGetCurrentContext(), imageRect, originalImage.CGImage);
CGContextSetFillColorWithColor(UIGraphicsGetCurrentContext(),[UIColor whiteColor].CGColor);
CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, originalImage.size.width, originalImage.size.height));
UIImage *returnImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return returnImage;
}
I created a Pod from #maggix's answer:
pod 'UIImage+InvertedImage'
This is a Swift 4.0 version of #maggix answer...
func invertImage(with originalImage: UIImage) -> UIImage? {
var image: UIImage?
UIGraphicsBeginImageContext(originalImage.size)
if let context = UIGraphicsGetCurrentContext() {
context.setBlendMode(.copy)
let imageRect = CGRect(x: 0, y: 0, width: originalImage.size.width, height: originalImage.size.height)
originalImage.draw(in: imageRect)
context.setBlendMode(.difference)
// translate/flip the graphics context (for transforming from CG* coords to UI* coords
context.translateBy(x: 0, y: originalImage.size.height)
context.scaleBy(x: 1.0, y: -1.0)
//mask the image
context.clip(to: imageRect, mask: originalImage.cgImage!)
context.setFillColor(UIColor.white.cgColor)
context.fill(CGRect(x: 0, y:0, width: originalImage.size.width, height: originalImage.size.height))
image = UIGraphicsGetImageFromCurrentImageContext()
}
UIGraphicsEndImageContext()
return image
}

UITableView with static cell - different separation color per section?

I have UITableView with static cells in 4 sections done in Storyboard. However, I want to change the separator color for one section ([UIColor clearColor]). How can I do that??? Is it actually possible?
I can set the separatorColor to clearColor for the entire table, but not only for one specific section.
Screenshot of table view section:
AFAIK there is no method for this. But you can put a background image to the cell which has a separator at the bottom and set separatorstyle to UITableViewCellSeparatorStyleNone. So you have your own separator in every cell.
Maybe you can achieve your goal by setting the header text for the section to an empty string.
One approach would to create your own UIView subclass and do your own custom drawing in drawRect:. You would take this view and add it as the backgroundView of your table view cell. Something like this:
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];
// Drawing code
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 1.0);
// Draw black line
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGFloat components[] = {0.0, 0.0, 0.0, 0.3};
CGColorRef blackColor = CGColorCreate(colorspace, components);
CGContextSetStrokeColorWithColor(context, blackColor);
CGContextMoveToPoint(context, 0, rect.size.height - 1.5);
CGContextAddLineToPoint(context, rect.size.width, rect.size.height - 1.5);
CGContextStrokePath(context);
CGColorRelease(blackColor);
// Draw white bottom line
CGFloat whiteComponents[] = {1.0, 1.0, 1.0, 0.75f};
CGColorRef whiteColor = CGColorCreate(colorspace, whiteComponents);
CGContextSetStrokeColorWithColor(context, whiteColor);
CGContextMoveToPoint(context, 0, rect.size.height - 0.5);
CGContextAddLineToPoint(context, rect.size.width, rect.size.height - 0.5);
CGContextStrokePath(context);
CGColorRelease(whiteColor);
// Draw top white line
CGFloat whiteTransparentComponents[] = {1.0, 1.0, 1.0, 0.45};
CGColorRef whiteTransparentColor = CGColorCreate(colorspace, whiteTransparentComponents);
CGContextSetStrokeColorWithColor(context, whiteTransparentColor);
CGContextMoveToPoint(context, 0, 0.5);
CGContextAddLineToPoint(context, rect.size.width, 0.5);
CGContextStrokePath(context);
CGColorRelease(whiteTransparentColor);
CGColorSpaceRelease(colorspace);
}

CoreGraphics draw an image on a white canvas

I have a source image which has a variable width and height, which I must show on a fullscreen iPad UIImageView but with addition of borders around the image itself. So my task is to create a new image with a white border around it, but not overlapping on the image itself. I'm currently doing it with overlapping via this code:
- (UIImage*)imageWithBorderFromImage:(UIImage*)source
{
CGSize size = [source size];
UIGraphicsBeginImageContext(size);
CGRect rect = CGRectMake(0, 0, size.width, size.height);
[source drawInRect:rect blendMode:kCGBlendModeNormal alpha:1.0];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
CGContextSetLineWidth(context, 40.0);
CGContextStrokeRect(context, rect);
UIImage *testImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return testImg;
}
Can anyone tell me how do I first draw a white canvas that is 40 pixels bigger in each direction than the source image and then draw that image on it?
I adjusted your code to make it work. Basically what it does:
Set canvas size to the size of your image + 2*margins
Fill the whole canvas with background color (white in your case)
Draw your image in the appropriate rectangle (with initial size and required margins)
Resulting code is:
- (UIImage*)imageWithBorderFromImage:(UIImage*)source
{
const CGFloat margin = 40.0f;
CGSize size = CGSizeMake([source size].width + 2*margin, [source size].height + 2*margin);
UIGraphicsBeginImageContext(size);
[[UIColor whiteColor] setFill];
[[UIBezierPath bezierPathWithRect:CGRectMake(0, 0, size.width, size.height)] fill];
CGRect rect = CGRectMake(margin, margin, size.width-2*margin, size.height-2*margin);
[source drawInRect:rect blendMode:kCGBlendModeNormal alpha:1.0];
UIImage *testImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return testImg;
}

Drawing to a view from a function

I can draw a line by placing the following into a UIView and connecting it to a storyboard View.
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 5.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, 10, 50);
CGContextStrokePath(context);
CGColorSpaceRelease(colorspace);
CGColorRelease(color);
}
However, what I want to do is to draw a line whenever a button is pressed. To do this I assume I need to write some code into an IBAction. My problem is that I cannot simply place the above code into the IBAction as it gives me an error.
- (IBAction)draw:(id)sender{
//Place code here
}
My question is, how can I draw a line each time the button is pressed?
How do I connect similar code to draw a different line that will be triggered when I press a button
To draw on a UIView you have to subclass your UIView
In .h
#MyCustomView : UIView {
}
#end
in .m
#implementation MyCustomView
- (void) drawRect: (CGRect) rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 5.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, 10, 50);
CGContextStrokePath(context);
CGColorSpaceRelease(colorspace);
CGColorRelease(color);
}
In your ViewController
-(void)methodCallCustomView{
}
- (IBAction)draw:(id)sender{
[self methodCallCustomView];
}
So you want the drawRect: method to be called when you press a button? If so, send the message setNeedsDisplay to the view that has the drawRect: code.