Search code examples
iosswiftuilabelcore-graphicscagradientlayer

CAGradientLayer on UILabel can't be rotated


I want a horizontal color gradient as the text color of my UILabel. So I'm using a CAGradientLayer as described in https://developer.apple.com/reference/quartzcore/cagradientlayer. The gradient is rendered perfectly on the text, but vertically.

CATransform3DMakeRotation as apple described doesn't rotate the gradient.

In this answer it says that the CAGradientLayer needs to be added to a View or other Layer first to make the rotation work.

So I tried to add it as a sublayer to my UILabel and remove it after the rendering, but it won't transform the gradient on the text, but adds a horizontal gradient rectangle on top of it, in the size of the UILabel but rotated 90°.

Here's my code:

extension UILabel {
func addGradient() {
    // Get size of the label
    let size = CGSize(width: frame.width, height: frame.width)

    let gradientLayer = CAGradientLayer()
    gradientLayer.frame = CGRect(x: 0, y: 0, width: size.height, height: size.width)

    gradientLayer.colors = [
        UIColor.gradientBlue.cgColor,
        UIColor.gradientPink.cgColor,
        UIColor.gradientOrange.cgColor
    ]

    //        layer.addSublayer(gradientLayer)
    gradientLayer.transform = CGAffineTransform

    // This does not work
    gradientLayer.transform = CATransform3DMakeRotation(CGFloat.pi / 2, 0, 0, 1)

    UIGraphicsBeginImageContext(size)
    gradientLayer.render(in: UIGraphicsGetCurrentContext()!)

    // Create UIImage from Gradient
    let gradientImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    //        gradientLayer.removeFromSuperlayer()

    textColor = UIColor.init(patternImage: gradientImage!)
}
}

Solution

  • you can use

        gradientLayer.startPoint = CGPoint.init(x: 0, y: 0)
        gradientLayer.endPoint = CGPoint.init(x: 1, y: 1)
    

    for diagonal gradient. you can play with those points however you want to achieve different results.