iPhone上UIView和UILabel上的渐变

iPhone上UIView和UILabel上的渐变,iphone,ios,cocoa-touch,gradient,Iphone,Ios,Cocoa Touch,Gradient,可能重复: 我的应用程序需要在UIView或UILabel中显示文本,但背景必须是与真实UIColor相反的渐变。使用图形程序创建所需的外观并不好,因为文本可能会因服务器返回的数据而异 有人知道解决这个问题的最快方法吗? 非常感谢您的想法。您可以使用核心图形绘制渐变,正如Mike在回答中指出的那样。作为更详细的示例,您可以创建一个UIView子类作为UILabel的背景。在该UIView子类中,重写drawRect:方法并插入类似以下内容的代码: - (void)drawRect:(CGRec

可能重复:

我的应用程序需要在
UIView
UILabel
中显示文本,但背景必须是与真实
UIColor
相反的渐变。使用图形程序创建所需的外观并不好,因为文本可能会因服务器返回的数据而异

有人知道解决这个问题的最快方法吗?
非常感谢您的想法。

您可以使用核心图形绘制渐变,正如Mike在回答中指出的那样。作为更详细的示例,您可以创建一个
UIView
子类作为
UILabel
的背景。在该
UIView
子类中,重写
drawRect:
方法并插入类似以下内容的代码:

- (void)drawRect:(CGRect)rect 
{
    CGContextRef currentContext = UIGraphicsGetCurrentContext();

    CGGradientRef glossGradient;
    CGColorSpaceRef rgbColorspace;
    size_t num_locations = 2;
    CGFloat locations[2] = { 0.0, 1.0 };
    CGFloat components[8] = { 1.0, 1.0, 1.0, 0.35,  // Start color
         1.0, 1.0, 1.0, 0.06 }; // End color

    rgbColorspace = CGColorSpaceCreateDeviceRGB();
    glossGradient = CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations);

    CGRect currentBounds = self.bounds;
    CGPoint topCenter = CGPointMake(CGRectGetMidX(currentBounds), 0.0f);
    CGPoint midCenter = CGPointMake(CGRectGetMidX(currentBounds), CGRectGetMidY(currentBounds));
    CGContextDrawLinearGradient(currentContext, glossGradient, topCenter, midCenter, 0);

    CGGradientRelease(glossGradient);
    CGColorSpaceRelease(rgbColorspace); 
}
此特定示例创建了从
ui视图顶部到其垂直中心绘制的白色光泽样式渐变。您可以将
ui视图
backgroundColor
设置为您喜欢的任何颜色,该光泽度将绘制在该颜色之上。也可以使用
CGContextDrawRadialGradient
函数绘制径向渐变

您只需适当调整此
UIView
的大小,并将
UILabel
添加为它的子视图,即可获得所需的效果


编辑(4/23/2009):根据St3fan的建议,我已经在代码中将视图的框架替换为其边界。这纠正了视图原点不是(0,0)的情况。

您也可以使用一个像素宽的图形图像作为渐变,并设置view属性以展开图形以填充视图(假设您考虑的是简单的线性渐变,而不是某种放射状图形).

我是在一个具有UIImageView子视图的视图中实现这一点的。ImageView指向的图像是渐变。然后我在UIView中设置了背景色,我有一个彩色渐变视图。接下来,我使用我需要的视图,我画的所有东西都在这个渐变视图下。通过在ImageView顶部添加第二个视图,您可以选择绘图是在渐变线下方还是上方…

我意识到这是一个较旧的线程,但供将来参考:

从iPhone SDK 3.0开始,通过使用新的
CAGradientLayer
,可以非常轻松地实现自定义渐变,而无需子类化或图像:

 UIView *view = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 100)] autorelease];
 CAGradientLayer *gradient = [CAGradientLayer layer];
 gradient.frame = view.bounds;
 gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor blackColor] CGColor], (id)[[UIColor whiteColor] CGColor], nil];
 [view.layer insertSublayer:gradient atIndex:0];

看看CAGradientLayer文档。您可以选择指定起点和终点(如果您不希望直线渐变从顶部到底部),甚至可以指定映射到每种颜色的特定位置。

注意:以下结果适用于旧版本的iOS,但在iOS 13上测试时,不会出现步进。我不知道删除了哪个版本的iOS的步进


当使用
cGradientLayer
时,与
cGradient
相反,渐变不是平滑的,但有明显的阶跃。见:


为了获得更吸引人的结果,最好使用
CGGradient

这是我得到的工作结果-将xCode的IB中的UIButton设置为透明/清晰,并且没有bg图像

UIColor *pinkDarkOp = [UIColor colorWithRed:0.9f green:0.53f blue:0.69f alpha:1.0];
UIColor *pinkLightOp = [UIColor colorWithRed:0.79f green:0.45f blue:0.57f alpha:1.0];

CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = [[shareWordButton layer] bounds];
gradient.cornerRadius = 7;
gradient.colors = [NSArray arrayWithObjects:
                   (id)pinkDarkOp.CGColor,
                   (id)pinkLightOp.CGColor,
                   nil];
gradient.locations = [NSArray arrayWithObjects:
                      [NSNumber numberWithFloat:0.0f],
                      [NSNumber numberWithFloat:0.7],
                      nil];

[[recordButton layer] insertSublayer:gradient atIndex:0];

Mirko Froehlich的回答对我很有用,除非我想使用自定义颜色。诀窍是用色调、饱和度和亮度而不是RGB指定UI颜色

CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = myView.bounds;
UIColor *startColour = [UIColor colorWithHue:.580555 saturation:0.31 brightness:0.90 alpha:1.0];
UIColor *endColour = [UIColor colorWithHue:.58333 saturation:0.50 brightness:0.62 alpha:1.0];
gradient.colors = [NSArray arrayWithObjects:(id)[startColour CGColor], (id)[endColour CGColor], nil];
[myView.layer insertSublayer:gradient atIndex:0];

要获取颜色的色调、饱和度和亮度,请使用内置的xcode颜色选择器并转到HSB选项卡。在该视图中,色调是以度为单位测量的,因此将该值除以360以获得您希望在代码中输入的值。

我尝试了此代码,但它不正确。与其将currentFrame设置为self.frame,不如将其设置为self.bounds。你说得对,谢谢你指出这一点。后来我修改了自己的代码,但忘记了这需要更新。当视图的原点的Y位置不同于0时,您会遇到这种情况。然后从垂直中心偏移绘制渐变。这可以应用于UIImage或UIImageView以获得任何具有渐变的图像吗?您可以将其放置在UIImageView上以添加渐变。要更改图像的内容,您可能需要先将图像绘制到上下文中,在该上下文中绘制图像上方的渐变,然后将上下文另存为新图像。您能否告诉我使用以下内容时如何确定颜色:CGFloat组件[8]={1.0、1.0、1.0、0.35、1.0、1.0、1.0、1.0、0.06};你如何知道什么是1和0.35?例如,如果我的评论吸引了任何人的眼球,因为他们考虑上面的其他解决方案,就做这一个。这很容易(但请记住,您需要添加QuartzCore框架并在您的类中导入
#import
)。有人可能会应用其他效果,例如,cornerRadius。他们必须在此处添加更多代码:
view.layer.masksToBounds=YES以确保事情顺利进行。我的实验表明,具有固定梯度图像的图像显示出比使用CAGradientLayer.Hm更好的性能。当我使用此解决方案时,我的标签文本消失。@hivehiks我发现如果我对
UILabel
使用
CAGradientLayer
,我必须将
backgroundColor
设置为
[UIColor clearColor]
(或等效)您介意发布与Mirko Froehlich使用CGGradient的示例等效的代码吗?Brad Larson使用CGGradient的上述代码已经足够好了。我本想对其中一个答案发表评论,但我的观点还不够。重要提示:我最近删除了我的CGGradient代码,并将其替换为CAGradientLayer。你知道为什么吗?我画了30个单元格,对性能的影响很大。CAGradient在性能方面要好得多(解释了细微的质量差异)。如果要添加渐变的视图高度很小,我想CAGradientLayer是您可以负担得起的折衷方案。如果视图高度显著,最好使用CGGradient。因此,它是h