How to set the Radius Corners to View using DrawRect Method? - objective-c

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];
}

Related

Shapes in sprite kit

How do you make a circle or another shape in sprite kit I have seen some that use CGPath but i haven't really ever used CGPath ever . I was able to make a square with SKSpritenode but I can't seem to make triangles or circles.
This creates an SKShapeNode and sets its path property to a circle path with radius 16.
SKShapeNode *shape = [SKShapeNode node];
CGRect rect = CGRectMake(0, 0, 32, 32);
shape.path = [self circleInRect:rect];
shape.strokeColor = [SKColor greenColor];
shape.fillColor = [SKColor redColor];
shape.position = CGPointMake(100,100);
[self addChild:shape];
This method returns a CGPath object initialized with a oval path
- (CGPathRef) circleInRect:(CGRect)rect
{
// Adjust position so path is centered in shape
CGRect adjustedRect = CGRectMake(rect.origin.x-rect.size.width/2, rect.origin.y-rect.size.height/2, rect.size.width, rect.size.height);
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithOvalInRect:adjustedRect];
return bezierPath.CGPath;
}
Here's a triangle path...
- (CGPathRef) triangleInRect:(CGRect)rect
{
CGFloat offsetX = CGRectGetMidX(rect);
CGFloat offsetY = CGRectGetMidY(rect);
UIBezierPath* bezierPath = [UIBezierPath bezierPath];
[bezierPath moveToPoint: CGPointMake(offsetX, 0)];
[bezierPath addLineToPoint: CGPointMake(-offsetX, offsetY)];
[bezierPath addLineToPoint: CGPointMake(-offsetX, -offsetY)];
[bezierPath closePath];
return bezierPath.CGPath;
}
Code snippet to create Triangle using Sprite Kit
SKShapeNode* leftContainer = [SKShapeNode node];
leftContainer.position = CGPointMake(CGRectGetMidX(self.frame),
CGRectGetMidY(self.frame));
CGMutablePathRef pathLeftContainer = CGPathCreateMutable();
// Move to position and Draws line to form a triangle
CGPathMoveToPoint(pathLeftContainer, NULL, 60, 100);
CGPathAddLineToPoint(pathLeftContainer, 0, 120, 160);
CGPathAddLineToPoint(pathLeftContainer, 0,180,100);
CGPathAddLineToPoint(pathLeftContainer, 0,60,100);
[leftContainer setPath:pathLeftContainer];
leftContainer.lineWidth = 10.0;
leftContainer.strokeColor = [UIColor redColor];
leftContainer.physicsBody = [SKPhysicsBody bodyWithEdgeChainFromPath:leftContainer.path];
leftContainer.physicsBody.dynamic = FALSE;
[leftContainer.physicsBody setAllowsRotation:FALSE];
[self addChild:leftContainer];
CGPathRelease(pathLeftContainer);
Code snippet to create Circle using Sprite Kit
SKShapeNode* leftContainer = [SKShapeNode node];
leftContainer.position = CGPointMake(CGRectGetMidX(self.frame),
CGRectGetMidY(self.frame));
CGMutablePathRef pathLeftContainer = CGPathCreateMutable();
// Draw circle with radius 20
CGPathAddArc(pathLeftContainer, NULL, 0, 20, 20, 0, 2*M_PI, true);
[leftContainer setPath:pathLeftContainer];
leftContainer.lineWidth = 10.0;
leftContainer.strokeColor = [UIColor redColor];
leftContainer.physicsBody = [SKPhysicsBody bodyWithEdgeChainFromPath:leftContainer.path];
leftContainer.physicsBody.dynamic = FALSE;
[leftContainer.physicsBody setAllowsRotation:FALSE];
[self addChild:leftContainer];
CGPathRelease(pathLeftContainer);

Drawing multiple arcs using Core Graphics

I'm trying to draw two concentric circles using Core Graphics. I would expect the following code to draw a blue circle and a smaller white circle inside, however it just draws the blue circle. What am I missing?
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextAddArc(c, self.bounds.size.width/2, self.bounds.size.height/2, 100, 0, M_PI * 2, true);
CGContextSetFillColor(c, CGColorGetComponents([[UIColor blueColor] CGColor]));
CGContextFillPath(c);
CGContextAddArc(c, self.bounds.size.width/2, self.bounds.size.height/2, 90, 0, M_PI * 2, true);
CGContextSetFillColor(c, CGColorGetComponents([[UIColor whiteColor] CGColor]));
CGContextFillPath(c);
You are setting the fill color in an unnecessarily indirect way. Do this instead:
CGContextAddArc(c, self.bounds.size.width/2, self.bounds.size.height/2, 100, 0, M_PI * 2, true);
CGContextSetFillColorWithColor(c, [[UIColor blueColor] CGColor]);
CGContextFillPath(c);
CGContextAddArc(c, self.bounds.size.width/2, self.bounds.size.height/2, 90, 0, M_PI * 2, true);
CGContextSetFillColorWithColor(c, [[UIColor whiteColor] CGColor]);
CGContextFillPath(c);
Or, even better, just use UIKit's drawing methods directly:
[[UIColor blueColor] setFill];
[[UIBezierPath bezierPathWithArcCenter:CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2) radius:100 startAngle:0 endAngle:M_PI * 2 clockwise:YES] fill];
[[UIColor whiteColor] setFill];
[[UIBezierPath bezierPathWithArcCenter:CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2) radius:90 startAngle:0 endAngle:M_PI * 2 clockwise:YES] fill];
Your code is failing because [[UIColor whiteColor] CGColor] returns a color in the "gray" colorspace, which has only two components, a "gray" value (0 for black, 1 for white) and an alpha value. In this case, the context is RGBA, so CGContextSetFillColor expects to see 4 components, three for RGB and one for alpha.
The documentation for CGContextSetFillColor points out:
Note that the preferred API to use is now
CGContextSetFillColorWithColor.

CGContextRef not drawing

I'm trying to draw a circle for my Mac Application. The Code is:
- (void)mouseMoved:(NSEvent*)theEvent {
NSPoint thePoint = [[self.window contentView] convertPoint:[theEvent locationInWindow] fromView:nil];
NSLog(#"mouse moved: %f % %f",thePoint.x, thePoint.y);
CGRect circleRect = CGRectMake(thePoint.x, thePoint.y, 20, 20);
CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
CGContextSetRGBFillColor(context, 0, 0, 255, 1.0);
CGContextSetRGBStrokeColor(context, 0, 0, 255, 0.5);
CGContextFillEllipseInRect(context, CGRectMake(circleRect.origin.x, circleRect.origin.y, 25, 25));
CGContextStrokeEllipseInRect(context, circleRect);
[self needsDisplay];
}
- (void)mouseMoved: is called perfectly and I can see the correct x and y coordinates in NSLog. But I do not get any circles... surprisingly: If I'm minimizing my application and reopening it (so it "updates" NSView) the circles are perfectly drawn!
mouseMoved is NOT right place to draw anything, unless you're drawing onto the offscreen buffer. If you are going to draw on screen, save thePoint and any other necessary data, call [self setNeedsDisplay:YES] and draw in the drawRect:(NSRect)rect method.
Also, I can't see a reason to use CGContextRef while there is much more "friendly" NSGraphicsContext. Although, it's matter of taste.
An example of the drawing code:
- (void)mouseMoved:(NSEvent*)theEvent {
// thePoint must be declared as the class member
thePoint = [[self.window contentView] convertPoint:[theEvent locationInWindow] fromView:nil];
[self setNeedsDisplay:YES];
}
- (void)drawRect:(NSRect)rect
{
NSRect ovalRect = NSMakeRect(thePoint.x - 100, thePoint.y - 100, 200, 200);
NSBezierPath* oval = [NSBezierPath bezierPathWithOvalInRect:ovalRect];
[[NSColor blueColor] set];
[oval fill];
[[NSColor redColor] set];
[oval stroke];
}

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;
}