iOS - How to draw a transparent triangle in view - iphone

I am trying to do a custom tab bar with a transparent triangle that points into the tab bar's view.
Right now I am drawing a linear gradient and a gloss in the drawRect method for the background of this tab bar. I just need to add the transparent triangle on there. I know how to draw a triangle. I just need to know how to make it transparent to show the background beneath the tab bar view.
Anyone know how to do this?
Update
Here is the current code:
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);
}
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);
CGColorSpaceRelease(colorSpace);
}
- (void)drawTriangle
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGPoint pt1 = CGPointMake(0.0f, 0.0f);
CGPoint pt2 = CGPointMake(10.0f, 10.0f);
CGPoint pt3 = CGPointMake(20.0f, 0.0f);
CGPoint vertices[] = {pt1, pt2, pt3, pt1};
CGContextBeginPath(context);
CGContextAddLines(context, vertices, 3);
CGContextClosePath(context);
CGContextClip(context);
}
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGColorRef lightColor = [UIColor colorWithRed:65.0f/255.0f green:64.0f/255.0f
blue:66.0f/255.0f alpha:1.0].CGColor;
CGColorRef darkColor = [UIColor colorWithRed:37.0/255.0 green:31.0/255.0
blue:32.0/255.0 alpha:1.0].CGColor;
[self drawTriangle];
CGRect viewRect = self.bounds;
drawGlossAndGradient(context, viewRect, lightColor, darkColor);
}
I added the clip suggested below but that just made my background with the gradient and the gloss dissappear and the triangle become gray. Does anyone know what I am doing wrong here?

If you draw this gradient in drawRect: method just add clipping path before it.
Example:
-(void)drawRect:(CGRect)rect {
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGPoint vertices[] = {coordinates of vertices};
CGContextBeginPath(ctx);
CGContextAddLines(ctx, vertices, sizeof(vertices)/sizeof(CGPoint));
CGContextClosePath(ctx);
CGContextClip(ctx);
// draw the gradient
}
Vertices - is an array with 7 points. 1 point per each corner of self.bounds and 3 points which are define the triangle.
For example:
(0) (1) (3) (4)
_____ ________________
| \ / |
| V |
| (2) |
(6) |_______________________|(5)
CGPoint vertices[7] = {CGPointZero, // origin
p1, p2, p3, // vertices of the triangle
{self.bounds.size.width, 0},
{self.bounds.size.width, self.bounds.size.height},
{0, self.bounds.size.height}
}

If anybody needs, this is a code to draw a colored triangle in a UITableView without using UIImageView. This method is good because, the size of triangle can vary and it is drawn programmatically. Also, you can probably change colors and make triangle transparent.
#implementation RRTriangleView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, 0.0, 0.0);
CGPathAddLineToPoint(path, NULL, - self.bounds.size.height / 2.0, self.bounds.size.height / 2.0);
CGPathAddLineToPoint(path, NULL, 0.0, self.bounds.size.height);
CGPathAddLineToPoint(path, NULL, 0.0f, 0.0f);
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
[shapeLayer setPath:path];
[shapeLayer setFillColor:[COLOR_CUSTOM_LIGHT_BLUE CGColor]];
[shapeLayer setStrokeColor:[COLOR_CUSTOM_LIGHT_BLUE CGColor]];
[shapeLayer setPosition:CGPointMake(self.bounds.size.width, 0.0f)];
[[self layer] addSublayer:shapeLayer];
CGPathRelease(path);
}
return self;
}
Init this TriangleView and add it to your cell, when it is selected :
- (RRTriangleView *)triangleView
{
if (! _triangleView) {
_triangleView = [[RRTriangleView alloc] initWithFrame:self.bounds];
_triangleView.layer.backgroundColor = [[UIColor clearColor] CGColor];
_triangleView.clipsToBounds = NO;
}
return _triangleView;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
//[super setSelected:selected animated:animated];
if (selected) {
[self addSubview:self.triangleView];
}
else {
[self.triangleView removeFromSuperview];
}
}
The size of triangleView is like your cell's view, it is transparent and it is drawn above.

I beleive that
[view setBackgroundColor:[UIColor clearColor]];
[view setOpaque:NO];
will make your view transparent.

Related

Drawing Shadowed Rectangle at iOS

I am trying to draw an image like below with libraries in iOS; but i couldn't.
I think it is very easy to draw but i couldn't achieve.
After i accomplish to draw i will place a label over it.
Use this as your drawRect method:
- (void)drawRect:(CGRect)rect
//// General Declarations
CGContextRef context = UIGraphicsGetCurrentContext();
//// Shadow Declarations
UIColor* shadow = [UIColor blackColor];
CGSize shadowOffset = CGSizeMake(1, 1);
CGFloat shadowBlurRadius = 2;
//// Frames
CGRect frame = rect;
//// Abstracted Graphic Attributes
CGRect shadowBoxRect = CGRectMake(CGRectGetMinX(frame) + 0, CGRectGetMinY(frame) + 0, 40, 40);
CGFloat shadowBoxCornerRadius = 4;
//// ShadowBox Drawing
UIBezierPath* shadowBoxPath = [UIBezierPath bezierPathWithRoundedRect: shadowBoxRect cornerRadius: shadowBoxCornerRadius];
[[UIColor lightGrayColor] setFill];
[shadowBoxPath fill];
////// ShadowBox Inner Shadow
CGRect shadowBoxBorderRect = CGRectInset([shadowBoxPath bounds], -shadowBlurRadius, -shadowBlurRadius);
shadowBoxBorderRect = CGRectOffset(shadowBoxBorderRect, -shadowOffset.width, -shadowOffset.height);
shadowBoxBorderRect = CGRectInset(CGRectUnion(shadowBoxBorderRect, [shadowBoxPath bounds]), -1, -1);
UIBezierPath* shadowBoxNegativePath = [UIBezierPath bezierPathWithRect: shadowBoxBorderRect];
[shadowBoxNegativePath appendPath: shadowBoxPath];
shadowBoxNegativePath.usesEvenOddFillRule = YES;
CGContextSaveGState(context);
{
CGFloat xOffset = shadowOffset.width + round(shadowBoxBorderRect.size.width);
CGFloat yOffset = shadowOffset.height;
CGContextSetShadowWithColor(context,
CGSizeMake(xOffset + copysign(0.1, xOffset), yOffset + copysign(0.1, yOffset)),
shadowBlurRadius,
shadow.CGColor);
[shadowBoxPath addClip];
CGAffineTransform transform = CGAffineTransformMakeTranslation(-round(shadowBoxBorderRect.size.width), 0);
[shadowBoxNegativePath applyTransform: transform];
[[UIColor grayColor] setFill];
[shadowBoxNegativePath fill];
}
CGContextRestoreGState(context);
}
Inner shadows are hard to do with CoreGraphics -- basically, you need to negate your path and draw a drop shadow below it, clipped to your original path.
You can take a look at PaintCode and it will show you the code. It has a 15-min demo mode if you don't want to purchase it, that should be enough for your needs.
You could try this:
#import <QuartzCore/QuartzCore.h>
and in your code , after making the your view set these:
self.layer.cornerRadius = x;
self.layer.masksToBounds = TRUE;
This allows you to have rounded corners on your view. And if you calculate the radius to match your view , you should get the desired look.
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor grayColor];
}
return self;
}
- (void)drawRect:(CGRect)rect
{
CGContextRef context =UIGraphicsGetCurrentContext();
CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
// And draw with a blue fill color
CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1.0);
// Draw them with a 2.0 stroke width so they are a bit more visible.
CGContextSetLineWidth(context, 2.0);
CGContextAddRect(context, self.bounds);
CGContextStrokePath(context);
// Close the path
CGContextClosePath(context);
// Fill & stroke the path
CGContextDrawPath(context, kCGPathFillStroke);
self.layer.cornerRadius = self.bounds.size.width/12;
self.layer.masksToBounds = TRUE;
}
I think it will be helpful to you.
Try the below code where myView is the UIView to which you want to set the shadow.
myView.layer.cornerRadius = 5.0f;
myView.layer.masksToBounds = YES;
[myView.layer setShadowColor:[[UIColor blackColor] colorWithAlphaComponent: 0.5]];
[myView.layer setShadowOffset:CGSizeMake(0, -1)];
Hope this helps.-

Two-color background for UILabel

I got a requirements to display a UILabel with background split between two colors, like in this image:
(colors here are black at the bottom and 50% gray at the top - but this is not important). I tried setting the label's background colour to 50% grey in the interface builder and then do this in the code:
CALayer *sl1 = [[[CALayer alloc] init] autorelease];
sl1.frame = CGRectMake(0, lbl.frame.size.height / 2, lbl.frame.size.width, score1.frame.size.height/2);
sl1.backgroundColor = [[UIColor blackColor] CGColor];
[lbl.layer insertSublayer:sl1 atIndex:0];
Unfortunately, this resulted in the black part being drawn over the text, so the label looks like this:
which is, needless to say, is not something I need. So how can I get this background without turning to custom images? The issue is I need to have UILabel's like this in several places, different sizes - so I would need to create multiple versions of the background image.
Any ideas? Thanks.
this works:
UILabel* myLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 100, 100, 50)];
myLabel.text = #"Ciao";
myLabel.textColor = [UIColor greenColor];
UIGraphicsBeginImageContext(CGSizeMake(100, 50));
CGContextRef context = UIGraphicsGetCurrentContext();
// drawing with a gray fill color
CGContextSetRGBFillColor(context, 0.4, 0.4, 0.4, 1.0);
// Add Filled Rectangle,
CGContextFillRect(context, CGRectMake(0.0, 0.0, 100, 50));
// drawing with a black fill color
CGContextSetRGBFillColor(context, 0., 0., 0., .9);
// Add Filled Rectangle,
CGContextFillRect(context, CGRectMake(0.0, 25, 100, 25));
UIImage* resultingImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
myLabel.backgroundColor = [UIColor colorWithPatternImage:resultingImage];
[self.view addSubview:myLabel];
Use UIColor's +colorWithPatternImage:. Pass in a 1px by the UILabel's height image and it will be "tiled" across the the width of the view.
myLabel.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"label-background.png"]];
first you have to subclass the UILabel and override it's drawRect: method like this for gradient background
- (void)drawRect:(CGRect)rect
{
//////////////GET REFERENCE TO CURRENT GRAPHICS CONTEXT
CGContextRef context = UIGraphicsGetCurrentContext();
//////////////CREATE BASE SHAPE WITH ROUNDED CORNERS FROM BOUNDS
CGRect activeBounds = self.bounds;
CGFloat cornerRadius = 10.0f;
CGFloat inset = 6.5f;
CGFloat originX = activeBounds.origin.x + inset;
CGFloat originY = activeBounds.origin.y + inset;
CGFloat width = activeBounds.size.width - (inset*2.0f);
CGFloat height = activeBounds.size.height - (inset*2.0f);
CGRect bPathFrame = CGRectMake(originX, originY, width, height);
CGPathRef path = [UIBezierPath bezierPathWithRoundedRect:bPathFrame cornerRadius:cornerRadius].CGPath;
//////////////CREATE BASE SHAPE WITH FILL AND SHADOW
CGContextAddPath(context, path);
CGContextSetFillColorWithColor(context, [UIColor colorWithRed:210.0f/255.0f green:210.0f/255.0f blue:210.0f/255.0f alpha:1.0f].CGColor);
CGContextSetShadowWithColor(context, CGSizeMake(0.0f, 1.0f), 6.0f, [UIColor colorWithRed:0.0f/255.0f green:0.0f/255.0f blue:0.0f/255.0f alpha:1.0f].CGColor);
CGContextDrawPath(context, kCGPathFill);
//////////////CLIP STATE
CGContextSaveGState(context); //Save Context State Before Clipping To "path"
CGContextAddPath(context, path);
CGContextClip(context);
//////////////DRAW GRADIENT
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
size_t count = 3;
CGFloat locations[3] = {0.0f, 0.57f, 1.0f};
CGFloat components[12] =
{ 0.0f/255.0f, 0.0f/255.0f, 0.0f/255.0f, 1.0f, //1
5.0f/255.0f, 5.0f/255.0f, 5.0f/255.0f, 1.0f, //2
10.0f/255.0f, 10.0f/255.0f, 10.0f/255.0f, 1.0f}; //3
CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, count);
CGPoint startPoint = CGPointMake(activeBounds.size.width * 0.5f, 0.0f);
CGPoint endPoint = CGPointMake(activeBounds.size.width * 0.5f, activeBounds.size.height);
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
CGColorSpaceRelease(colorSpace);
CGGradientRelease(gradient);
}
This will draw black to white gradient background
May this will help you
Happy Codding :)
the above code is from this site http://mobile.tutsplus.com/tutorials/iphone/ios-sdk-uialertview-custom-graphics/

Using CAGradientLayer as backround while also drawing in context with drawRect:

I'm writing an app that plots some data into a simple graph and sometimes want to draw out the scale in the background. To do this I have a UIView subclass which acts as the graph background and simply use the drawRect: method to draw the scale (data elements will get added as subviews to this view, since I want the user to be able to interact with them).
However, I also want a gradient background color and have used CAGradientLayer for this purpose (as suggested in this thread). But when I add this as a sublayer, the gradient background appears, but nothing I do in drawRect: shows!
I'm sure I'm missing something simple or have misunderstood how to use CAGradientLayer or something, so any help or suggestions is appreciated!
This is the relevant code in my UIView subclass:
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
// Create a gradient background
CAGradientLayer *gradientBackground = [CAGradientLayer layer];
gradientBackground.frame = self.bounds;
gradientBackground.colors = [NSArray arrayWithObjects:(id)[[UIColor grayColor] CGColor], (id)[[UIColor whiteColor] CGColor], nil];
[self.layer insertSublayer:gradientBackground atIndex:0];
}
return self;
}
- (void)drawRect:(CGRect)rect {
// Get the graphics context
CGContextRef context = UIGraphicsGetCurrentContext();
// Clear the context
CGContextClearRect(context, rect);
// Call actual draw method
[self drawInContext:context];
}
-(void)drawInContext:(CGContextRef)context {
CGFloat step;
// Draw Y scale
if (displayYScale) {
CGContextSetRGBStrokeColor(context, 0, 0, 0, kScaleLineAlpha);
if (yAxisScale.mode == FCGraphScaleModeData) {
step = (self.frame.size.height-(yAxisScale.padding*2))/yAxisScale.dataRange.maximum;
for (int i = 0; i <= yAxisScale.dataRange.maximum; i++) {
CGContextMoveToPoint(context, 0.0f, (step*i)+yAxisScale.padding);
CGContextAddLineToPoint(context, self.frame.size.width, (step*i)+yAxisScale.padding);
}
} else if (yAxisScale.mode == FCGraphScaleModeDates) {
int units = (int)[yAxisScale units];
step = (self.frame.size.height-(yAxisScale.padding*2))/units;
for (int i = 0; i <= units; i++) {
CGContextMoveToPoint(context, 0.0f, (step*i)+yAxisScale.padding);
CGContextAddLineToPoint(context, self.frame.size.width, (step*i)+yAxisScale.padding);
}
}
CGContextStrokePath(context);
}
// Draw X scale
if (displayXScale) {
CGContextSetRGBStrokeColor(context, 0, 0, 255, kScaleLineAlpha);
if (xAxisScale.mode == FCGraphScaleModeData) {
step = (self.frame.size.width-(xAxisScale.padding*2))/xAxisScale.dataRange.maximum;
for (int i = 0; i <= xAxisScale.dataRange.maximum; i++) {
CGContextMoveToPoint(context, (step*i)+xAxisScale.padding, 0.0f);
CGContextAddLineToPoint(context, (step*i)+xAxisScale.padding, self.frame.size.height);
}
} else if (xAxisScale.mode == FCGraphScaleModeDates) {
int units = (int)[xAxisScale units];
step = (self.frame.size.width-(xAxisScale.padding*2))/units;
for (int i = 0; i <= units; i++) {
CGContextMoveToPoint(context, (step*i)+xAxisScale.padding, 0.0f);
CGContextAddLineToPoint(context, (step*i)+xAxisScale.padding, self.frame.size.height);
}
}
CGContextStrokePath(context);
}
}
Thanks!
/Anders
Since you're drawing anyway, you can also just draw your own gradient:
// the colors
CGColorRef topColor = [[UIColor grayColor] CGColor];
CGColorRef bottomColor = [[UIColor whiteColor] CGColor];
NSArray *colors =
[NSArray arrayWithObjects: (id)topColor, (id)bottomColor, nil];
CGFloat locations[] = {0, 1};
CGGradientRef gradient =
CGGradientCreateWithColors(CGColorGetColorSpace(topColor),
(CFArrayRef)colors, locations);
// the start/end points
CGRect bounds = self.bounds;
CGPoint top = CGPointMake(CGRectGetMidX(bounds), bounds.origin.y);
CGPoint bottom = CGPointMake(CGRectGetMidX(bounds), CGRectGetMaxY(bounds));
// draw
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextDrawLinearGradient(context, gradient, top, bottom, 0);
CGGradientRelease(gradient);
Sublayers will show above anything done in drawRect. Add another sublayer on top of the gradient layer that uses your view as the delegate, in that layers drawLayer:inContext: callback do what you're currently doing in drawRect.

How to fill a path with gradient in drawRect:?

filling a path with a solid color is easy enough:
CGPoint aPoint;
for (id pointValue in points)
{
aPoint = [pointValue CGPointValue];
CGContextAddLineToPoint(context, aPoint.x, aPoint.y);
}
[[UIColor redColor] setFill];
[[UIColor blackColor] setStroke];
CGContextDrawPath(context, kCGPathFillStroke);
I'd like to draw a gradient instead of solid red, but I am having trouble.
I've tried the code listed in the Question/Answer: Gradients on UIView and UILabels On iPhone
which is:
CAGradientLayer *gradient = [CAGradientLayer layer];
[gradient setFrame:rect];
[gradient setColors:[NSArray arrayWithObjects:(id)[[UIColor blueColor] CGColor],
(id)[[UIColor whiteColor] CGColor], nil]];
[[self layer] setMasksToBounds:YES];
[[self layer] insertSublayer:gradient atIndex:0];
However, this paints the entire view that this is in with the gradient, covering up my original path.
I would clip to the path you want to fill, and use CGContextDrawLinearGradient. Here is a simple implementation of drawRect: as an example:
- (void) drawRect:(CGRect)rect
{
// Create a gradient from white to red
CGFloat colors [] = {
1.0, 1.0, 1.0, 1.0,
1.0, 0.0, 0.0, 1.0
};
CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceRGB();
CGGradientRef gradient = CGGradientCreateWithColorComponents(baseSpace, colors, NULL, 2);
CGColorSpaceRelease(baseSpace), baseSpace = NULL;
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextAddEllipseInRect(context, rect);
CGContextClip(context);
CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
CGGradientRelease(gradient), gradient = NULL;
CGContextRestoreGState(context);
CGContextAddEllipseInRect(context, rect);
CGContextDrawPath(context, kCGPathStroke);
}

Rounded rect with Gradient color

I have not really done much programming with Core Graphics. And I tend to stick with QuartzCore now that it does a lot of what I need through the layer property :)
However, I have a UIView, which is currently gradient. I'd like to add rounded corners to this UIView and the layer property does not do this when I draw the gradient:
- (void)drawRect:(CGRect)rect {
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGGradientRef glossGradient;
CGColorSpaceRef rgbColorspace;
size_t num_locations = 2;
CGFloat locations[2] = { 0.0, 1.0 };
CGFloat components[8] = { 1.0, 1.0, 1.0, 0.95, // Start color
1.0, 1.0, 1.0, 0.60 }; // End color
rgbColorspace = CGColorSpaceCreateDeviceRGB();
glossGradient = CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations);
CGRect currentBounds = self.bounds;
CGPoint topCenter = CGPointMake(CGRectGetMidX(currentBounds), 0.0f);
CGPoint midCenter = CGPointMake(CGRectGetMidX(currentBounds), CGRectGetMaxY(currentBounds));
CGContextDrawLinearGradient(currentContext, glossGradient, topCenter, midCenter, 0);
CGGradientRelease(glossGradient);
CGColorSpaceRelease(rgbColorspace);
}
I am not really sure where I should be rounding in the drawRect method. Thanks.
Have you checked previous question postings? I read one a while back about masking UIViews. I think the same applies pretty much on all objects which use drawRect
How to mask a square image into an image with round corners in the iPhone SDK?
Here's what I did, and it works fine as far as I can tell.
First, I borrowed Mr NilObject's code snippet from the above mentioned post.
I modified it to fit in an object (as he wrote it as a C function instead of a method)
I subclass UIView to create my own custom view. I overload initWithRect: to make my background transparent.
So basically:
set transparent background (in init), or clipping will be uggly
in drawRect, first clip, then draw inside the clipped area
The following is a working example:
//
// TeleView.m
//
#import "TeleView.h"
#implementation TeleView
/**** in init methods, set background to transparent,
otherwise, clipping shows a black background ****/
- (id) initWithFrame:(CGRect)frame {
if((self = [super initWithFrame:frame])) {
[self setBackgroundColor:[UIColor colorWithWhite:0.0f alpha:0.0f]];
}
return self;
}
- (void) clipCornersToOvalWidth:(float)ovalWidth height:(float)ovalHeight
{
float fw, fh;
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect rect = CGRectMake(0.0f, 0.0f, self.frame.size.width, self.frame.size.height);
if (ovalWidth == 0 || ovalHeight == 0) {
CGContextAddRect(context, rect);
return;
}
CGContextSaveGState(context);
CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect));
CGContextScaleCTM (context, ovalWidth, ovalHeight);
fw = CGRectGetWidth (rect) / ovalWidth;
fh = CGRectGetHeight (rect) / ovalHeight;
CGContextMoveToPoint(context, fw, fh/2);
CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1);
CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1);
CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1);
CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1);
CGContextClosePath(context);
CGContextRestoreGState(context);
}
-(void)drawRect:(CGRect)rect {
CGContextRef currentContext = UIGraphicsGetCurrentContext();
/**** here is what I modified. ****/
[self clipCornersToOvalWidth:20.0f height:20.0f];
CGContextClip(currentContext);
/**** below this is your own code ****/
CGGradientRef glossGradient;
CGColorSpaceRef rgbColorspace;
size_t num_locations = 2;
CGFloat locations[2] = { 0.0, 1.0 };
CGFloat components[8] = { 1.0, 0.0, 0.0, 0.60, // Start color
0.0, 1.0, 0.0, 0.40 }; // End color
rgbColorspace = CGColorSpaceCreateDeviceRGB();
glossGradient = CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations);
CGRect currentBounds = self.bounds;
CGPoint topCenter = CGPointMake(CGRectGetMidX(currentBounds), 0.0f);
CGPoint midCenter = CGPointMake(CGRectGetMidX(currentBounds), CGRectGetMaxY(currentBounds));
CGContextDrawLinearGradient(currentContext, glossGradient, topCenter, midCenter, 0);
CGGradientRelease(glossGradient);
CGColorSpaceRelease(rgbColorspace);
}
#end
NSArray *colors = [NSArray arrayWithObjects:fromColor.CGColor,toColor.CGColor, nil];
NSNumber *stopOne = [NSNumber numberWithFloat:0.0];
NSNumber *stopTwo = [NSNumber numberWithFloat:1.0];
NSArray *locations = [NSArray arrayWithObjects:stopOne, stopTwo, nil];
CAGradientLayer *headerLayer = [CAGradientLayer layer];
headerLayer.colors = colors;
headerLayer.locations = locations;
headerLayer.borderColor = borderColor.CGColor; // border line color**strong text**
headerLayer.borderWidth = width;// For Thickness of border line
headerLayer.cornerRadius = radius;//For Rounded Corner if You want to make rounded Corner
headerLayer.frame = frame;
[view.layer insertSublayer:headerLayer atIndex:0];
Also make sure to import "QuartzCore" framework