7

I'm trying to use a 3 colour gradient to colour my text in Xcode and its seemingly impossible to get the results I'm looking for. I have had success with the following but this only gives me two colours through the gradient.

@IBOutlet weak var textSample: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()
    textSample.textColor = UIColor(patternImage: gradientImage(size: textSample.frame.size, color1: CIColor(color: UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)), color2: CIColor(color: UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 0.2))))
}

func gradientImage(size: CGSize, color1: CIColor, color2: CIColor) -> UIImage {

    let context = CIContext(options: nil)
    let filter = CIFilter(name: "CILinearGradient")
    var startVector: CIVector
    var endVector: CIVector

    filter!.setDefaults()

    startVector = CIVector(x: size.width * 0.5, y: 0)
    endVector = CIVector(x: size.width * 0.5, y: size.height * 0.8)

    filter!.setValue(startVector, forKey: "inputPoint0")
    filter!.setValue(endVector, forKey: "inputPoint1")
    filter!.setValue(color1, forKey: "inputColor0")
    filter!.setValue(color2, forKey: "inputColor1")

    let image = UIImage(cgImage: context.createCGImage(filter!.outputImage!, from: CGRect(x: 0, y: 0, width: size.width, height: size.height))!)
    return image
}

What I'd like to do is have 3 locations with three colours:

location1: y:0.0
location2: y:0.8
location3: y:1.0

color1: UIColour(red: 1, green: 1, blue: 1, alpha: 0.2)
color2: UIColour(red: 1, green: 1, blue: 1, alpha: 1.0)
color3: UIColour(red: 1, green: 1, blue: 1, alpha: 0.45)

I've been trying to simplify it by just adding that gradient with the 3 locations to a UIView, but it seems that no matter what I do for masking that UIView with the UILabel, nothing works. Any Suggestions would be extremely helpful. I've attached a picture with what I get with my above code, and an example of what I'd like to achieve if possible.

enter image description here

mediarts
  • 1,511
  • 4
  • 18
  • 29
  • I'm assuming it isn't trivial to do this for three layers but you've managed to do it for two. So why not split the IUImage in half, implement the gradient for both halves and then reattach? – Roy Falk Apr 15 '17 at 17:35

1 Answers1

2

Maybe better choose will be CAGradientLayer (AppCoda), and then adding it to label as described here. Here is an example:

var labelBackground = UIView(frame: label.frame)
label.backgroundColor = UIColor.clear
label.frame = label.bounds
var gradLayer = CAGradientLayer()
gradLayer.frame = labelBackground.layer.bounds
gradLayer.colors = [UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0).CGColor, UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 0.2).CGColor, UIColor(red: 1, green: 1, blue: 1, alpha: 0.45).CGColor]
gradientLayer.locations = [0.0, 0.8, 1.0]    
labelBackground.layer.addSublayer(gradLayer)
labelBackground.addSubview(label)
view.addSubview(labelBackground)
Community
  • 1
  • 1
Samuel Tulach
  • 1,319
  • 13
  • 38
  • This seams to create a rectangle, that has the gradient in it, in a different location then the original label, and moves the original label to the top left of the screen. – mediarts May 10 '17 at 23:17