UILabel,颜色渐变到标签的某个高度

时间:2016-12-24 12:09:07

标签: ios swift uikit uilabel calayer

我希望从下面的图片中获得效果 - UILabel显示进度 X 作为从底部到 X%高度的渐变标签。标签的剩余(100 - X)%将具有不同的颜色。

desired effect

现在我唯一想到的就是创建两个带有灰色背景的UIViews和带有渐变颜色的一个UILabel。将渐变视图放在灰色视图上方并设置其高度以匹配当前进度。然后只需使用标签作为这两个视图的掩码。为了更好的说明,我附上了一张描述我建议的解决方案虽然我对它不满意,因为它不是很优雅。

suggested solution

是否有可能以不同且更优雅的方式实现这一目标?理想情况下,只需通过继承rewrite

3 个答案:

答案 0 :(得分:1)

您可以将Core Animation与CATextLayer和CAGradientLayer一起使用。

import PlaygroundSupport

let bgView = UIView(frame: CGRect(x: 0, y: 0, width: 80, height: 80))
bgView.backgroundColor = UIColor.black
PlaygroundPage.current.liveView = bgView

let textLayer = CATextLayer()
textLayer.frame = bgView.frame
textLayer.string = "70"
textLayer.fontSize = 60

let gradientLayer = CAGradientLayer()
gradientLayer.frame = bgView.frame
gradientLayer.colors = [
    UIColor.gray.cgColor,
    UIColor(red: 1, green: 122.0/255.0, blue: 0, alpha: 1).cgColor,
    UIColor(red: 249.0/255.0, green: 1, blue: 0, alpha: 1).cgColor
]

//Here you can adjust the filling
gradientLayer.locations = [0.5, 0.51, 1]

gradientLayer.mask = textLayer
bgView.layer.addSublayer(gradientLayer)

enter image description here

答案 1 :(得分:1)

您可以使用图层和蒙版进行此操作,但实际上更容易使用图案图像中的UIColor设置文本颜色。这段代码可行,但是为UILabel子类化并为类提供应用和/或更新图像的方法可能会更好。我说这更容易,因为我发现处理文本图层有点痛苦,以使尺寸完美,标签可以通过adjustsFontSizeToFitWidth改变字体大小。

 override func viewDidLayoutSubviews() {
    label.textColor = UIColor(patternImage: partialGradient(forViewSize: label.frame.size, proportion: 0.65))
}

func partialGradient(forViewSize size: CGSize, proportion p: CGFloat) -> UIImage {
    UIGraphicsBeginImageContextWithOptions(size, false, 0)

    let context = UIGraphicsGetCurrentContext()


    context?.setFillColor(UIColor.darkGray.cgColor)
    context?.fill(CGRect(origin: .zero, size: size))

    let c1 = UIColor.orange.cgColor
    let c2 = UIColor.red.cgColor

    let top = CGPoint(x: 0, y: size.height * (1.0 - p))
    let bottom = CGPoint(x: 0, y: size.height)

    let colorspace = CGColorSpaceCreateDeviceRGB()

    if let gradient = CGGradient(colorsSpace: colorspace, colors: [c1, c2] as CFArray, locations: [0.0, 1.0]){
        // change 0.0 above to 1-p if you want the top of the gradient orange
        context?.drawLinearGradient(gradient, start: top, end: bottom, options: CGGradientDrawingOptions.drawsAfterEndLocation)
    }


    let img = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return img!
}

enter image description here

答案 2 :(得分:0)

您可以继承UILabel并在draw(_ rect: CGRect)函数中绘制您想要的内容。或者如果你想快速做到这一点,你也可以进行子类化并添加渐变子视图。不要忘记在layoutSubviews()函数中调整它的大小。