EDIT:Vẽ một UIView tròn với độ dốc và thả bóng
cuối cùng tôi đã tìm thấy một giải pháp đơn giản thực cho vấn đề này, bằng cách sử dụng lớp CAGradientLayer, và các chức năng vẽ CALayer.
Ole Begemann đã phát hành một trình bao bọc UIView tuyệt vời cho lớp CAGradientLayer có tên OBGradientView.
Lớp này cho phép bạn dễ dàng tạo ra một UIView gradient trong ứng dụng của bạn.
Sau đó bạn sử dụng chức năng CALayer vẽ thêm các góc bo tròn và thả các giá trị bóng:
// 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 quên thêm khuôn khổ QuartzCore để dự án của bạn.
HỎI ORIGINAL:
Tôi đã được làm việc trên một điều khiển tùy chỉnh mà là một nút hình chữ nhật tròn, đầy với một linear gradient, và có một bóng thả. Tôi đã điền hai bước đầu tiên bằng cách sử dụng câu trả lời này: link text
Vấn đề của tôi bây giờ là thêm bóng thả dưới hình dạng kết quả. Thực ra, ngữ cảnh đã được cắt bớt thành đường tròn được làm tròn, vì vậy khi tôi sử dụng hàm CGContextSetShadow, nó không vẽ nó.
Tôi đã cố gắng giải quyết vấn đề này bằng cách vẽ bản lề tròn hai lần, đầu tiên với màu đồng bằng, do đó, nó vẽ bóng và sau đó vẽ lại bằng tô màu tô.
Nó kinda làm việc, nhưng tôi vẫn có thể thấy một vài điểm ảnh ở các góc của hình phát sinh từ việc bốc thăm đầu tiên với một màu đơn giản, như bạn có thể nhìn thấy trên phiên bản này zoom:
http://img269.imageshack.us/img269/6489/capturedcran20100701192.png
nó gần như là tốt, nhưng chưa hoàn hảo ...
đây là -drawRect tôi: thực hiện:
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);
}
Bất kỳ ý tưởng về cách làm điều này theo một cách khác?
Cảm ơn!
Cảm ơn bạn vì lời giải thích rất chi tiết này! Ví dụ của bạn hoạt động hoàn hảo. Tôi chỉ cần sửa CGGradientRef của bạn từ CGGradientRef * normalGradient thành CGGradientRef normalGradient. –
Bạn có thể giải thích cách các đường tiếp tuyến và các điểm được tạo ra từ các đối số không? Tôi không hiểu làm thế nào bạn có thể tạo ra hai dòng và hai điểm từ 4 đối số ... – ryyst
@super_tomtom ai đó có thể giải thích cách hoạt động này? Tôi đã subclasses một UIView tùy chỉnh và thực hiện chức năng này nó ghi đè drawRect nhưng tôi vẫn nhận được không có góc tròn hoặc bóng đổ? –