gpt4 book ai didi

iphone - 绘制带有渐变和阴影的圆形 UIView

转载 作者:行者123 更新时间:2023-12-03 18:24:23 25 4
gpt4 key购买 nike

编辑:

我终于找到了一个真正简单的解决方案来解决这个问题,使用 CAGradientLayer类,以及 CALayer 绘图功能。
Ole Begemann 为 CAGradientLayer 类发布了一个很棒的 UIView 包装器,名为 OBGradientView .
此类允许您在应用程序中轻松创建渐变 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);
}

关于如何以其他方式做到这一点有什么想法吗?

谢谢!

最佳答案

为了创建具有渐变背景和阴影的圆角 View ,请执行以下操作:

第一部分与问题中提供的内容非常相似,它使用 CGPathAddArcToPoint 创建圆角矩形路径,如 this article 中所述。 。这是一张图片来帮助我理解: alt text

第二部分的工作原理如下:

在图形上下文上启用阴影,添加刚刚定义的路径,然后填充该路径。您不能仅将阴影应用于路径本身(路径不是图形状态的一部分),因此您需要填充路径才能显示阴影(我想描边路径也可能有效?)。您不能简单地将阴影应用于渐变,因为它并不是真正的标准填充(有关更多信息,请参阅 this post)。

一旦你有了一个可以创建阴影的填充圆角矩形,你就需要在它上面绘制渐变。因此,再次添加路径以设置剪切区域,然后使用 CGContextDrawLinearGradient 绘制渐变。我认为您无法像之前的标准填充步骤那样轻松地用渐变“填充”路径,因此您可以用渐变填充绘图区域,然后剪辑到您感兴趣的圆角矩形区域英寸。

- (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;
}

关于iphone - 绘制带有渐变和阴影的圆形 UIView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3160220/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com