-(void)setTopRightCornerWithRadious:(CGFloat)radious View:(UIView*)vw
{
UIGraphicsGetCurrentContext();
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:vw.bounds byRoundingCorners:UIRectCornerTopRight cornerRadii:CGSizeMake(radious, radious)];
[maskPath closePath];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = vw.bounds;
maskLayer.path = maskPath.CGPath;
vw.layer.mask=maskLayer;
if (vw.layer.borderColor) {
UIColor *color=[UIColor colorWithCGColor:vw.layer.borderColor];
[color setStroke];
maskLayer.accessibilityPath.lineWidth=1.0f;
[maskLayer.accessibilityPath stroke];
}
}
-(void)setAllBorderForView:(UIView*)vw Color:(UIColor*)color Thickness:(CGFloat)thick
{
if (vw) {
vw.layer.borderWidth=thick;
vw.layer.borderColor=color.CGColor;
}
}
I wish to draw a border surrounded by these two button. I tried so many times with CAShapeLayer and UIBezierPath, but failed, may be I missed some thing. Some of them solve this problem using UIView, but I don't want that. I only want to solve the issues only by using the CAShapeLayer and/or UIBezierPath.
Here is my smaple code... WHere is my fault???? At very first i set the border, then I tried to set the corner. For few time may the border color exist or may not exist.
If you just need to have a border around the button, add stroke to the button bezier path.
- (void)drawRect: (CGRect)frame
{
UIBezierPath* rectangle2Path = [UIBezierPath bezierPathWithRoundedRect: CGRectMake(x,y,widht,height) byRoundingCorners: UIRectCornerTopRight cornerRadii: CGSizeMake(17.25, 17.25)];
[rectangle2Path closePath];
[UIColor.grayColor setFill];
[rectangle2Path fill];
[UIColor.redColor setStroke];
rectangle2Path.lineWidth = 1;
[rectangle2Path stroke];
}
Or If you want to have space between the border and the button bezier path, then you should add two bezier paths. One for button, and another one for border.
- (void)drawRect: (CGRect)frame
{
UIBezierPath* rectanglePath = [UIBezierPath bezierPathWithRoundedRect: CGRectMake(CGRectGetMinX(frame), CGRectGetMinY(frame), floor((CGRectGetWidth(frame)) * 1.00000 + 0.5), floor((CGRectGetHeight(frame)) * 1.00000 + 0.5)) byRoundingCorners: UIRectCornerTopRight cornerRadii: CGSizeMake(28, 28)];
[rectanglePath closePath];
[UIColor.redColor setStroke];
rectanglePath.lineWidth = 1;
[rectanglePath stroke];
UIBezierPath* rectangle2Path = [UIBezierPath bezierPathWithRoundedRect: CGRectMake(CGRectGetMinX(frame) + 7, CGRectGetMinY(frame) + 8, 103, 62) byRoundingCorners: UIRectCornerTopRight cornerRadii: CGSizeMake(26, 26)];
[rectangle2Path closePath];
[UIColor.grayColor setFill];
[rectangle2Path fill];
}
In your custom button class you set this:
UIBezierPath outerPAth= [UIBezierPath bezirePath];
[[UIColor WhiteColor] setStroke];
outlinePath.lineWidth=5.0;
[outlinePath stroke];
I am trying to draw arc within a circle and fill the arc's. Here is the code i am using:
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextAddEllipseInRect(ctx, rect);
CGContextSetFillColor(ctx, CGColorGetComponents([[clrArray objectAtIndex:0] CGColor]));
CGContextFillPath(ctx);
CGFloat radius = 12.5;
CGFloat startAngle1 = DegreesToRadians(0);
CGFloat endAngle1 = DegreesToRadians(135);
CGFloat startAngle2 = DegreesToRadians(135);
CGFloat endAngle2 = DegreesToRadians(270);
//draw arc
CGPoint center = CGPointMake(radius,radius);
//Arc 1
CGContextAddArc(ctx,
center.x,
center.y,
radius,
startAngle1,
endAngle1,
YES);
[(UIColor*)[clrArray objectAtIndex:1] set];
CGContextFillPath(ctx);
//Arc 2
CGContextAddArc(ctx,
center.x,
center.y,
radius,
startAngle2,
endAngle2,
YES);
[(UIColor*)[clrArray objectAtIndex:2] set];
CGContextFillPath(ctx);
It is not drawing right. If i only provide one arc then if its angle is less than 180 then it is also not daring right. What i am doing wrong?
Edit: Here is the image of what is happening
I used start angle 0 and end angle 45 in this image
Got another solution using bezier Path
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGFloat radius = 50.0/2.0;
CGPoint center = CGPointMake(radius,radius);
CGFloat startAngle1 = DegreesToRadians(0);
CGFloat endAngle1 = DegreesToRadians(120);
CGFloat startAngle2 = DegreesToRadians(120);
CGFloat endAngle2 = DegreesToRadians(240);
CGContextSaveGState(ctx);
UIBezierPath* clip1 = [UIBezierPath bezierPathWithArcCenter:center
radius:radius
startAngle:startAngle1
endAngle:endAngle1
clockwise:YES];
[clip1 addLineToPoint:center];
[clip1 closePath];
[clip1 addClip];
UIBezierPath *arc1 = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 50, 50)];
[[UIColor blackColor] set];
[arc1 fill];
CGContextRestoreGState(ctx);
CGContextSaveGState(ctx);
UIBezierPath* clip2 = [UIBezierPath bezierPathWithArcCenter:center
radius:radius
startAngle:startAngle2
endAngle:endAngle2
clockwise:YES];
[clip2 addLineToPoint:center];
[clip2 closePath];
[clip2 addClip];
UIBezierPath *arc2 = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 50, 50)];
[[UIColor orangeColor] set];
[arc2 fill];
CGContextRestoreGState(ctx);
self.rating.text=#"4.5";
self.rating.adjustsFontSizeToFitWidth=YES;
self.rating.textColor = [UIColor blackColor];
self.rating.font = [UIFont fontWithName:#"Helvetica-Bold" size:8.0];
self.rating.layer.borderColor = [UIColor colorWithRed:.2 green:1 blue:0 alpha:1].CGColor;
self.rating.layer.borderWidth = 2.0f;
self.rating.textAlignment=NSTextAlignmentCenter;
self.rating.clipsToBounds=YES;
self.rating.layer.masksToBounds=YES;
when i do this i get the following o/p
But i need the label border to be filled 90% assuming max rating will be five and remaining red
There are lots of ways to do it, but one is to just draw two bezier paths, one for each side:
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, [[UIColor blueColor] CGColor]);
UIBezierPath *blueHalf = [UIBezierPath bezierPath];
[blueHalf addArcWithCenter:CGPointMake(100, 100) radius:90.0 startAngle:-M_PI_2 endAngle:M_PI_2 clockwise:YES];
[blueHalf setLineWidth:4.0];
[blueHalf stroke];
CGContextSetStrokeColorWithColor(context, [[UIColor redColor] CGColor]);
UIBezierPath *redHalf = [UIBezierPath bezierPath];
[redHalf addArcWithCenter:CGPointMake(100.0, 100.0) radius:90.0 startAngle:M_PI_2 endAngle:3.0 * M_PI_2 clockwise:YES];
[redHalf setLineWidth:4.0];
[redHalf stroke];
}
I'm trying a UIBezierPath for the first time and am trying to fill a graph I've drawn with a color but without success. This is what I've done within a custom UIView:
- (void)calculateGraphSize
{
self.topY = CGRectGetMinY(self.bounds);
self.bottomY = CGRectGetMaxY(self.bounds);
self.minX = CGRectGetMinX(self.bounds);
self.maxX = CGRectGetMaxX(self.bounds);
}
- (void) drawRect: (CGRect) rect
{
CGSize cornerRadius = CGSizeMake(10.0f, 10.0f);
[self calculateGraphSize];
UIBezierPath *graphBorder = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:UIRectCornerAllCorners cornerRadii:cornerRadius];
[[UIColor redColor] setFill];
[graphBorder fill];
UIBezierPath *barGraph = [UIBezierPath bezierPath];
barGraph.lineWidth = 2.0f;
CGPoint point = CGPointMake(self.minX, self.bottomY);
[barGraph moveToPoint:point];
point = CGPointMake(self.minX + 50, self.bottomY - 50);
[barGraph addLineToPoint:point];
point = CGPointMake(self.minX + 100, self.bottomY - 75);
[barGraph addLineToPoint:point];
point = CGPointMake(self.minX + 200, self.bottomY);
[barGraph addLineToPoint:point];
[[UIColor blackColor] setStroke];
[[UIColor greenColor] setFill];
[barGraph closePath];
[barGraph stroke];
}
Just add [barGraph fill]:
[[UIColor blackColor] setStroke];
[[UIColor greenColor] setFill];
[barGraph closePath];
[barGraph fill];
[barGraph stroke];
You probably want to fill and then stroke as I can't remember if the fill will cover up the stroke (I always have to check ha!)
I have path with values and I want to make this gradient.
Here is the code:
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, [[UIColor colorWithRed:245.0/255.0 green:245.0/255.0 blue:171.0/255.0 alpha:0.6] CGColor]);
CGContextSetFillColorWithColor(context, [[UIColor colorWithRed:245.0/255.0 green:245.0/255.0 blue:171.0/255.0 alpha:0.6] CGColor]);
UIBezierPath *aPath = [UIBezierPath bezierPath];
[aPath moveToPoint:CGPointMake(30.0, 100.0)];
[aPath addLineToPoint:CGPointMake(200.0, 120.0)];
[aPath addLineToPoint:CGPointMake(300, 210)];
[aPath addLineToPoint:CGPointMake(300, 420)];
[aPath addLineToPoint:CGPointMake(30, 420.0)];
[aPath addLineToPoint:CGPointMake(30, 100.0)];
[aPath closePath];
[aPath fill];
Any pointers to figure out issue with this code?
First - I've created simple arrow with Bezier path:
UIBezierPath* bezierPath = [UIBezierPath bezierPath];
[bezierPath moveToPoint: CGPointMake(24.5, 1.5)];
[bezierPath addLineToPoint: CGPointMake(2.5, 14.5)];
[bezierPath addLineToPoint: CGPointMake(24.5, 28.5)];
[bezierPath addLineToPoint: CGPointMake(24.5, 1.5)];
[bezierPath closePath];
[[UIColor blackColor] setStroke];
bezierPath.lineWidth = 1;
[bezierPath stroke];
Then I've drawn simple linear gradient from black to white:
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = UIGraphicsGetCurrentContext();
NSArray* simpleLinearGradientColors = [NSArray arrayWithObjects:
(id)[UIColor blackColor].CGColor,
(id)[UIColor whiteColor].CGColor, nil];
CGFloat simpleLinearGradientLocations[] = {0, 1};
CGGradientRef simpleLinearGradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)simpleLinearGradientColors, simpleLinearGradientLocations);
// Bezier Drawing
UIBezierPath* bezierPath = [UIBezierPath bezierPath];
[bezierPath moveToPoint: CGPointMake(24.5, 1.5)];
[bezierPath addLineToPoint: CGPointMake(2.5, 14.5)];
[bezierPath addLineToPoint: CGPointMake(24.5, 28.5)];
[bezierPath addLineToPoint: CGPointMake(24.5, 1.5)];
[bezierPath closePath];
CGContextSaveGState(context);
[bezierPath addClip];
CGContextDrawLinearGradient(context, simpleLinearGradient, CGPointMake(2.5, 15), CGPointMake(24.5, 15), 0);
CGContextRestoreGState(context);
[[UIColor blackColor] setStroke];
bezierPath.lineWidth = 1;
[bezierPath stroke];
CGGradientRelease(simpleLinearGradient);
CGColorSpaceRelease(colorSpace);
That's what I got:
Basically you can create linear, radial gradient with bunch of settings (locations, colors) and of course you should modify code above.
1.Create .h and .m files for eg CustomGradientView
CustomGradientView.h file should look like this
#interface CustomGradientView : UIView
and CustomGradientView.m file should look like this
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
// color1 and color 2 u can take as u wish here i m taking for explaining
UIColor *color1=[UIColor whiteColor];
CGColorRef startColor =color1.CGColor;
UIColor *color2=[UIColor redColor];
CGColorRef endColor = color2.CGColor;
drawLinearGradient(context, rect, startColor, endColor);
//for rounded corners
CGPathRef p = [[UIBezierPath bezierPathWithRoundedRect:rect
5] CGPath];
CGContextAddRect(context, rect);
CGContextAddPath(context, p);
CGContextEOClip(context);
CGContextClearRect(context, rect);
}
then in the .xib files to which view you want to be gradient extend its class CustomGradientView instead of UIView
the drawLinearGradient method is in another class u have to import it
they are
Common.h
#import <Foundation/Foundation.h>
void drawLinearGradient(CGContextRef context, CGRect rect, CGColorRef startColor, CGColorRef endColor);
CGRect rectFor1PxStroke(CGRect rect);
void draw1PxStroke(CGContextRef context, CGPoint startPoint, CGPoint endPoint, CGColorRef color);
void drawGlossAndGradient(CGContextRef context, CGRect rect, CGColorRef startColor, CGColorRef endColor);
static inline double radians (double degrees) { return degrees * M_PI/180; }
CGMutablePathRef createArcPathFromBottomOfRect(CGRect rect, CGFloat arcHeight);
CGMutablePathRef createRoundedRectForRect(CGRect rect, CGFloat radius);
and Common.m
#import "Common.h"
CGRect rectFor1PxStroke(CGRect rect) {
return CGRectMake(rect.origin.x + 0.5, rect.origin.y + 0.5, rect.size.width - 1, rect.size.height - 1);
}
void drawLinearGradient(CGContextRef context, CGRect rect, CGColorRef startColor, CGColorRef endColor) {
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat locations[] = { 0.0, 1.0 };
NSArray *colors = [NSArray arrayWithObjects:(__bridge id)startColor, (__bridge id)endColor, nil];
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef) colors, locations);
CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
CGContextSaveGState(context);
CGContextAddRect(context, rect);
CGContextClip(context);
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
CGContextRestoreGState(context);
CGGradientRelease(gradient);
}
void draw1PxStroke(CGContextRef context, CGPoint startPoint, CGPoint endPoint, CGColorRef color) {
CGContextSaveGState(context);
CGContextSetLineCap(context, kCGLineCapSquare);
CGContextSetStrokeColorWithColor(context, color);
CGContextSetLineWidth(context, 1.0);
CGContextMoveToPoint(context, startPoint.x + 0.5, startPoint.y + 0.5);
CGContextAddLineToPoint(context, endPoint.x + 0.5, endPoint.y + 0.5);
CGContextStrokePath(context);
CGContextRestoreGState(context);
}
void drawGlossAndGradient(CGContextRef context, CGRect rect, CGColorRef startColor, CGColorRef endColor) {
drawLinearGradient(context, rect, startColor, endColor);
CGColorRef glossColor1 = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.35].CGColor;
CGColorRef glossColor2 = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.1].CGColor;
CGRect topHalf = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height/2);
drawLinearGradient(context, topHalf, glossColor1, glossColor2);
}
CGMutablePathRef createArcPathFromBottomOfRect(CGRect rect, CGFloat arcHeight) {
CGRect arcRect = CGRectMake(rect.origin.x, rect.origin.y + rect.size.height - arcHeight,
rect.size.width, arcHeight);
CGFloat arcRadius = (arcRect.size.height/2) + (pow(arcRect.size.width, 2) / (8*arcRect.size.height));
CGPoint arcCenter = CGPointMake(arcRect.origin.x + arcRect.size.width/2, arcRect.origin.y + arcRadius);
CGFloat angle = acos(arcRect.size.width / (2*arcRadius));
CGFloat startAngle = radians(180) + angle;
CGFloat endAngle = radians(360) - angle;
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddArc(path, NULL, arcCenter.x, arcCenter.y, arcRadius, startAngle, endAngle, 0);
CGPathAddLineToPoint(path, NULL, CGRectGetMaxX(rect), CGRectGetMinY(rect));
CGPathAddLineToPoint(path, NULL, CGRectGetMinX(rect), CGRectGetMinY(rect));
CGPathAddLineToPoint(path, NULL, CGRectGetMinX(rect), CGRectGetMaxY(rect));
return path;
}
CGMutablePathRef createRoundedRectForRect(CGRect rect, CGFloat radius) {