编辑:
我终于找到了一个真正简单的解决方案,使用CAGradientLayer类和 CALayer 绘图功能。Ole Begemann 为名为OBGradientView
的 CAGradientLayer 类发布了一个很棒的 UIView 包装器。
此类允许您在应用程序中轻松创建渐变 UIView。
然后,您使用CALayer绘图功能添加圆角和阴影值:
// 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];
不要忘记将 QuartzCore 框架添加到您的项目中。
原始问题:
我一直在研究一个自定义控件,它是一个圆角矩形按钮,填充了线性渐变,并有一个阴影。我已经使用这个答案填写了前两个步骤:link text
我现在的问题是在生成的形状下添加阴影。实际上,上下文已经被裁剪到圆角矩形路径,所以当我使用 CGContextSetShadow 函数时,它不会绘制它。
我尝试通过绘制圆角矩形两次来解决这个问题,首先使用纯色绘制阴影,然后使用渐变填充重新绘制它。
它有点工作,但我仍然可以在第一次用纯色绘制产生的形状的角落看到几个像素,正如你在这个缩放版本中看到的那样:
http://img269.imageshack.us/img269/6489/capturedcran20100701192.png
它几乎是好的,但还不完美......
这是我的 -drawRect: 实现:
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);
}
关于如何以另一种方式做到这一点的任何想法?
谢谢 !