UIView with rounded rectangle and drop shadow: shadow appears above rectangle
I've got a uiview subclass where I'm trying to draw a rounded rectangle with a drop shadow. Though it draws both elements, I can see shadow through the rounded rectangle fill. I'm new to CG so I'm probably missing something simple (though it doesn't seem to be the alpha of the fill which is set to 1). Here's the draw rect code.
- (void)drawRect:(CGRect)rect {
// get the contect
CGContextRef context = UIGraphicsGetCurrentContext();
//for the shadow, save the state then draw the shadow
CGContextSaveGState(context);
CGContextSetShadow(context, CGSizeMake(4,-5),开发者_JS百科 10);
//now draw the rounded rectangle
CGContextSetStrokeColorWithColor(context, [[UIColor blackColor] CGColor]);
CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1.0);
//since I need room in my rect for the shadow, make the rounded rectangle a little smaller than frame
CGRect rrect = CGRectMake(CGRectGetMinX(rect), CGRectGetMinY(rect), CGRectGetWidth(rect)-30, CGRectGetHeight(rect)-30);
CGFloat radius = self.cornerRadius;
// the rest is pretty much copied from Apples example
CGFloat minx = CGRectGetMinX(rrect), midx = CGRectGetMidX(rrect), maxx = CGRectGetMaxX(rrect);
CGFloat miny = CGRectGetMinY(rrect), midy = CGRectGetMidY(rrect), maxy = CGRectGetMaxY(rrect);
// Start at 1
CGContextMoveToPoint(context, minx, midy);
// Add an arc through 2 to 3
CGContextAddArcToPoint(context, minx, miny, midx, miny, radius);
// Add an arc through 4 to 5
CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius);
// Add an arc through 6 to 7
CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius);
// Add an arc through 8 to 9
CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius);
// Close the path
CGContextClosePath(context);
// Fill & stroke the path
CGContextDrawPath(context, kCGPathFillStroke);
//for the shadow
CGContextRestoreGState(context);
}
- (void)drawRect:(CGRect)rect
{
self.layer.masksToBounds = NO;
self.layer.shadowColor = [[UIColor whiteColor] CGColor];
self.layer.shadowOffset = CGSizeMake(0,2);
self.layer.shadowRadius = 2;
self.layer.shadowOpacity = 0.2;
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(20, 20)];
[[UIColor blackColor] setFill];
[path fill];
}
I don't think you can do this in a single pass. Hmm I changed your code as follows, which seems to work.
- (void)drawRect:(CGRect)rect
{
// get the contect
CGContextRef context = UIGraphicsGetCurrentContext();
//now draw the rounded rectangle
CGContextSetStrokeColorWithColor(context, [[UIColor blackColor] CGColor]);
CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 0.0);
//since I need room in my rect for the shadow, make the rounded rectangle a little smaller than frame
CGRect rrect = CGRectMake(CGRectGetMinX(rect), CGRectGetMinY(rect), CGRectGetWidth(rect)-30, CGRectGetHeight(rect)-30);
CGFloat radius = 45;
// the rest is pretty much copied from Apples example
CGFloat minx = CGRectGetMinX(rrect), midx = CGRectGetMidX(rrect), maxx = CGRectGetMaxX(rrect);
CGFloat miny = CGRectGetMinY(rrect), midy = CGRectGetMidY(rrect), maxy = CGRectGetMaxY(rrect);
{
//for the shadow, save the state then draw the shadow
CGContextSaveGState(context);
// Start at 1
CGContextMoveToPoint(context, minx, midy);
// Add an arc through 2 to 3
CGContextAddArcToPoint(context, minx, miny, midx, miny, radius);
// Add an arc through 4 to 5
CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius);
// Add an arc through 6 to 7
CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius);
// Add an arc through 8 to 9
CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius);
// Close the path
CGContextClosePath(context);
CGContextSetShadow(context, CGSizeMake(4,-5), 10);
CGContextSetStrokeColorWithColor(context, [[UIColor blackColor] CGColor]);
// Fill & stroke the path
CGContextDrawPath(context, kCGPathFillStroke);
//for the shadow
CGContextRestoreGState(context);
}
{
// Start at 1
CGContextMoveToPoint(context, minx, midy);
// Add an arc through 2 to 3
CGContextAddArcToPoint(context, minx, miny, midx, miny, radius);
// Add an arc through 4 to 5
CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius);
// Add an arc through 6 to 7
CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius);
// Add an arc through 8 to 9
CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius);
// Close the path
CGContextClosePath(context);
CGContextSetStrokeColorWithColor(context, [[UIColor blackColor] CGColor]);
CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1.0);
// Fill & stroke the path
CGContextDrawPath(context, kCGPathFillStroke);
}
}
Try this after you import QuartzCore/QuartzCore.h
yourView.layer.shadowColor = [[UIColor blackColor] CGColor];
yourView.layer.shadowOffset = CGSizeMake(10.0f, 10.0f);
yourView.layer.shadowOpacity = 1.0f;
yourView.layer.shadowRadius = 10.0f;
精彩评论