Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 3390914
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 18, 20262026-05-18T03:44:45+00:00 2026-05-18T03:44:45+00:00

EDIT: I finally found a real simple solution to this problem, using the CAGradientLayer

  • 0

EDIT:

I finally found a real simple solution to this problem, using the CAGradientLayer class, and the CALayer drawing functionalities.
Ole Begemann released a great UIView wrapper for CAGradientLayer class named OBGradientView.
This class allows you to easily create a gradient UIView in your application.
You then use the CALayer drawing functionalities to add the rounded corners and drop shadow values :

// Create the gradient view
OBGradientView *gradient = [[OBGradientView alloc] initWithFrame:someRect];
NSArray *colors = [NSArray arrayWithObjects:[UIColor redColor], [UIColor yellowColor], nil];
gradient.colors = colors;

// Set rounded corners and drop shadow
gradient.layer.cornerRadius = 5.0;
gradient.layer.shadowColor = [UIColor grayColor].CGColor;
gradient.layer.shadowOpacity = 1.0;
gradient.layer.shadowOffset = CGSizeMake(2.0, 2.0);
gradient.layer.shadowRadius = 3.0;

[self.view addSubview:gradient];
[gradient release];

Dont forget to add the QuartzCore framework to your project.

ORIGINAL QUESTION:

I have been working on a custom control that is a rounded rectangle button, filled with a linear gradient, and having a drop shadow.
I have filled the two first steps using this answer : link text

My problem is now to add a drop shadow under the resulting shape.
Actually, the context has been clipped to the rounded rect path, so when I use the CGContextSetShadow function, it doesn’t draw it.

I tried to solve this problem by drawing the rounded rect twice, first with a plain color, so it draws the shadow, and then redraw it with the gradient fill.

It kinda worked, but I still can see a few pixels at the corners of the shape resulting from the first draw with a plain color, as you can see on this zoomed version :

http://img269.imageshack.us/img269/6489/capturedcran20100701192.png

It is almost good, but not perfect yet…

Here is my -drawRect: implementation :

static void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight)
{
 float fw, fh;

 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 context = UIGraphicsGetCurrentContext();

 CGSize shadowOffset = CGSizeMake(10.0, 10.0);
 CGFloat blur = 5.0;

 rect.size.width -= shadowOffset.width + blur;
 rect.size.height -= shadowOffset.height + blur;

 CGContextSaveGState(context);
 addRoundedRectToPath(context, rect, _radius, _radius);
 CGContextSetShadow (context, shadowOffset, blur);
 CGContextDrawPath(context, kCGPathFill);
 CGContextRestoreGState(context);

 addRoundedRectToPath(context, rect, _radius, _radius);
    CGContextClip(context);

 CGFloat colors[] =
 {
  _gradientStartColor.red, _gradientStartColor.green, _gradientStartColor.blue, _gradientStartColor.alpha,
  _gradientEndColor.red, _gradientEndColor.green, _gradientEndColor.blue, _gradientEndColor.alpha
 };
 size_t num_locations = 2;
    CGFloat locations[2] = { 0.0, 1.0 };

 CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
 CGGradientRef gradient = CGGradientCreateWithColorComponents(rgb, colors, locations, num_locations);

 CGRect currentBounds = self.bounds;
 CGPoint gStartPoint = CGPointMake(CGRectGetMidX(currentBounds), 0.0f);
 CGPoint gEndPoint = CGPointMake(CGRectGetMidX(currentBounds), CGRectGetMaxY(currentBounds));
 CGContextDrawLinearGradient(context, gradient, gStartPoint, gEndPoint, 0);

 CGColorSpaceRelease(rgb);
 CGGradientRelease(gradient);
}

Any ideas on how to do this in another way ?

Thanks !

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-18T03:44:46+00:00Added an answer on May 18, 2026 at 3:44 am

    In order to create a rounded corner view with a gradient background and drop shadow, here’s what did:

    The first part is very similar to what was provided in the question, it creates a rounded rect path using CGPathAddArcToPoint as described very well in this article. Here’s a picture to help me understand it:
    alt text

    The second part works as follows:

    Enable shadowing on the graphics context, add the path that was just defined, then fill that path. You can’t apply the shadow to just the path itself (paths are not part of the graphics state), so you need to fill the path in order for the shadow to appear (I suppose a stroked path might also work?). You can’t simply apply the shadow to a gradient since it’s not really a standard fill (see this post for more info).

    Once you have a filled rounded rect that creates the shadow, you need to draw the gradient over top of that. So add the path a second time in order to set the clipping area, then draw the gradient using CGContextDrawLinearGradient. I don’t think you can easily “fill” a path with a gradient like you could with the earlier standard-fill step, so instead you fill the drawing area with the gradient and then clip to the rounded rectangle area that you’re interested in.

    - (void)drawRect:(CGRect)rect 
    {
        [super drawRect:rect];
    
        CGGradientRef gradient = [self normalGradient];
    
        CGContextRef ctx = UIGraphicsGetCurrentContext(); 
        CGMutablePathRef outlinePath = CGPathCreateMutable(); 
        float offset = 5.0;
        float w  = [self bounds].size.width; 
        float h  = [self bounds].size.height; 
        CGPathMoveToPoint(outlinePath, nil, offset*2.0, offset); 
        CGPathAddArcToPoint(outlinePath, nil, offset, offset, offset, offset*2, offset); 
        CGPathAddLineToPoint(outlinePath, nil, offset, h - offset*2.0); 
        CGPathAddArcToPoint(outlinePath, nil, offset, h - offset, offset *2.0, h-offset, offset); 
        CGPathAddLineToPoint(outlinePath, nil, w - offset *2.0, h - offset); 
        CGPathAddArcToPoint(outlinePath, nil, w - offset, h - offset, w - offset, h - offset * 2.0, offset); 
        CGPathAddLineToPoint(outlinePath, nil, w - offset, offset*2.0); 
        CGPathAddArcToPoint(outlinePath, nil, w - offset , offset, w - offset*2.0, offset, offset); 
        CGPathCloseSubpath(outlinePath); 
    
        CGContextSetShadow(ctx, CGSizeMake(4,4), 3); 
        CGContextAddPath(ctx, outlinePath); 
        CGContextFillPath(ctx); 
    
        CGContextAddPath(ctx, outlinePath); 
        CGContextClip(ctx);
        CGPoint start = CGPointMake(rect.origin.x, rect.origin.y);
        CGPoint end = CGPointMake(rect.origin.x, rect.size.height);
        CGContextDrawLinearGradient(ctx, gradient, start, end, 0);
    
        CGPathRelease(outlinePath);
    }
    
    - (CGGradientRef)normalGradient
    {
    
        NSMutableArray *normalGradientLocations = [NSMutableArray arrayWithObjects:
                                                   [NSNumber numberWithFloat:0.0f],
                                                   [NSNumber numberWithFloat:1.0f],
                                                   nil];
    
    
        NSMutableArray *colors = [NSMutableArray arrayWithCapacity:2];
    
        UIColor *color = [UIColor colorWithRed:0.2745 green:0.2745 blue:0.2745 alpha:1.0];
        [colors addObject:(id)[color CGColor]];
        color = [UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:1.0];
        [colors addObject:(id)[color CGColor]];
        NSMutableArray  *normalGradientColors = colors;
    
        int locCount = [normalGradientLocations count];
        CGFloat locations[locCount];
        for (int i = 0; i < [normalGradientLocations count]; i++)
        {
            NSNumber *location = [normalGradientLocations objectAtIndex:i];
            locations[i] = [location floatValue];
        }
        CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
    
        CGGradientRef normalGradient = CGGradientCreateWithColors(space, (CFArrayRef)normalGradientColors, locations);
        CGColorSpaceRelease(space);
    
        return normalGradient;
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

EDIT: This was formerly more explicitly titled: - Best solution to stop Kontiki's KHOST.EXE
Edit: This question was written in 2008, which was like 3 internet ages ago.
EDIT: This question is more about language engineering than C++ itself. I used C++
Edit: This was accidentally posted twice. Original: VB.NET Importing Classes I've seen some code
Edit: I have solved this by myself. See my answer below I have set
Edit: From another question I provided an answer that has links to a lot
EDIT: Learned that Webmethods actually uses NLST, not LIST, if that matters Our business
EDIT What small things which are too easy to overlook do I need to
Edit : Solved, there was a trigger with a loop on the table (read
edit #2: Question solved halfways. Look below As a follow-up question, does anyone know

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.