将一个CGGradient作为子图层添加到UILabel中会隐藏标签的文本

24

我想将渐变色作为标签的背景。 我使用了以下代码来实现,但问题是虽然渐变颜色出现在标签上,但文本不可见。 请帮忙。

lblPatientDetail.text=PatientsDetails;

lblPatientDetail.textColor=[UIColor blackColor];  

CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = lblPatientDetail.bounds;
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor whiteColor] CGColor],(id)[[UIColor colorWithRed:255/255.0 green:239/255.0 blue:215/255.0 alpha:1.0] CGColor],nil];  

[lblPatientDetail.layer addSublayer:gradient];

lblPatientDetail.backgroundColor=[UIColor clearColor];
6个回答

22

在UILabel中插入一个子层会隐藏文本,所以获取所需效果的最佳方法是将标签和渐变层添加到UIView中。

UIView *gradientLabelView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 30)];

CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = gradientLabelView.bounds;
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor whiteColor] CGColor],(id)[[UIColor colorWithRed:255/255.0 green:239/255.0 blue:215/255.0 alpha:1.0] CGColor],nil];

[gradientLabelView.layer addSublayer:gradient];

lblPatientDetail.frame = gradientLabelView.bounds;
lblPatientDetail.backgroundColor = [UIColor clearColor];
[gradientLabelView addSubview:lblPatientDetail];

[self addSubview:gradientLabelView];

1
我知道它正在添加到上面的文本中...你能告诉我如何将这个图层放在后面吗?我已经尝试了你建议的那行代码,但没有成功。我也改变了索引,但仍然无济于事 :) 请帮帮我,提前感谢你 :) - Fatema
1
我不确定,可能你不能在UILabels上实现这个。你可以尝试创建一个有渐变效果的UIView,然后将标签作为子视图添加上去。 - James P
2
谢谢James,我尝试了你的第二个选项 :) 在UIView上添加了渐变,然后将标签作为子视图添加 :-) - Fatema
将您修改后的UILabel的背景颜色更改为[UIColor clearColor]。如果您不这样做,UILabel的背景将默认为白色背景:P - jsetting32

2
建议使用UIView内的UILabel,这种方法可行。显然,在给背景设置渐变颜色后,UILabel内部不能有文本...不知道为什么...
以下是完整的解决方案代码...希望能对某些人有所帮助 :)
UIView *EnvironmentalsLabelView = [[UIView alloc] initWithFrame:CGRectMake(0, 300, 320, 20)];
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = EnvironmentalsLabelView.bounds;
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor darkGrayColor]CGColor], (id)[[UIColor blackColor]CGColor], nil];
[EnvironmentalsLabelView.layer insertSublayer:gradient atIndex:0];
[scroller addSubview:EnvironmentalsLabelView];

UILabel *EnviornmentalsLabelText = [[UILabel alloc] initWithFrame:EnvironmentalsLabelView.bounds];
[EnviornmentalsLabelText setFont:[UIFont fontWithName:@"Arial-BoldMT" size:12.0f]];
EnviornmentalsLabelText.textAlignment = NSTextAlignmentCenter;
EnviornmentalsLabelText.backgroundColor = [UIColor clearColor];
EnviornmentalsLabelText.text = @"Environmental Benefits";
[EnvironmentalsLabelView addSubview:EnviornmentalsLabelText];

愉快的编程!!!


我们能否在不使用额外视图的情况下完成相同的操作? - Raj Aggrawal

1

还有一个需要更正的问题。

如果您使用自动布局来放置自定义视图,可能会遇到这个问题 - http://prntscr.com/5tj7bx

因此,您的视图与子视图 - UILabel和subLayer -渐变层具有不同的大小。

我通过添加一个方法来解决这个问题。

class wResultView: UIView {
var label = UILabel()
var gradientLayer = CAGradientLayer()

override func layoutSubviews() {
    gradientLayer.frame = self.bounds
    label.frame = self.bounds
}
......

0

创建UIView的解决方案对于常规使用来说并不是很方便。让我为此建议一个可重复使用的解决方案。

import UIKit

@IBDesignable
class GradientTextLabel: UILabel {
    // MARK: - Public vars
    @IBInspectable var startColor: UIColor = .red { didSet { setNeedsDisplay() } }
    @IBInspectable var midColor: UIColor = .orange { didSet { setNeedsDisplay() } }
    @IBInspectable var endColor: UIColor = .yellow { didSet { setNeedsDisplay() } }
    @IBInspectable var vertical = false { didSet { setNeedsDisplay() } }
    
    // MARK: - Lifecycle methods
    override func layoutSubviews() {
        super.layoutSubviews()
        
        let gradient = getGradientLayer(bounds: bounds)
        textColor = gradientColor(bounds: bounds, gradientLayer: gradient)
    }
    
    override func prepareForInterfaceBuilder() {
        setNeedsDisplay()
    }
    
    // MARK: - Private methods
    private func getGradientLayer(bounds : CGRect) -> CAGradientLayer{
        let gradient = CAGradientLayer()
        gradient.frame = bounds
        gradient.colors = [startColor.cgColor, midColor.cgColor, endColor.cgColor]
        
        if vertical {
            gradient.startPoint = CGPoint(x: 0.5, y: 0.0)
            gradient.endPoint = CGPoint(x: 0.5, y: 1.0)
        } else {
            gradient.startPoint = CGPoint(x: 0.0, y: 0.5)
            gradient.endPoint = CGPoint(x: 1.0, y: 0.5)
        }
        
        return gradient
    }
    
    private func gradientColor(bounds: CGRect, gradientLayer :CAGradientLayer) -> UIColor? {
        UIGraphicsBeginImageContext(gradientLayer.bounds.size)
        //create UIImage by rendering gradient layer.
        gradientLayer.render(in: UIGraphicsGetCurrentContext()!)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        //get gradient UIcolor from gradient UIImage
        return UIColor(patternImage: image!)
    }
}

-1

您可以在UILabel中添加另一个UILabel,像这样。

class GradientLabel: UILabel {  

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        self.clipsToBounds = true
        DispatchQueue.main.async {
            self.applyGradient(with: Color.gradientColor, gradient: GradientOrientation.topLeftBottomRight)
            self.textColor = UIColor.white
        }
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1) {

            let label = UILabel(frame: CGRect(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height))
            label.text = self.text
            label.font = self.font
            label.textColor = self.textColor
            label.textAlignment = self.textAlignment
            self.text = ""
            self.addSubview(label)
        }
    }
}

extension UIView {

    func applyGradient(with colours: [UIColor], locations: [NSNumber]? = nil) {
        let gradient = CAGradientLayer()
        gradient.frame = self.bounds
        gradient.colors = colours.map { $0.cgColor }
        gradient.locations = locations
        self.layer.insertSublayer(gradient, at: 0)
    }

    func applyGradient(with colours: [UIColor], gradient orientation: GradientOrientation) {
        let gradient = CAGradientLayer()
        gradient.frame = self.bounds
        gradient.colors = colours.map { $0.cgColor }
        gradient.startPoint = orientation.startPoint
        gradient.endPoint = orientation.endPoint
        self.layer.insertSublayer(gradient, at: 0)
    }
}

-4
我认为你可以通过调整上述代码中的 alpha 值来创建一个渐变颜色。
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor whiteColor] CGColor],(id)[[UIColor colorWithRed:255/255.0 green:239/255.0 blue:215/255.0 alpha:0.1] CGColor],nil];

我通过这样做成功地实现了渐变效果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接