我終於找到了一個真正簡單的解決這個問題,使用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);
}
如何任何想法以另一種方式做到這一點?
謝謝!
謝謝你beno這個非常詳細的解釋!你的例子完美地工作。我只是將您的CGGradientRef聲明從CGGradientRef * normalGradient更正爲CGGradientRef normalGradient。 – 2010-11-23 15:07:50
你能解釋從參數創建切線和點的方式嗎?我不明白如何從4個參數中創建兩行和兩個點... – ryyst 2011-04-16 12:54:10
@super_tomtom有人可以解釋這是如何工作的嗎?我已經子類化一個自定義的UIView,並使這個函數它的drawRect覆蓋,但我仍然沒有圓角或投影? – 2011-04-19 20:31:17