skip to Main Content

is there any solution to apply tint colour as a gradient in swift

my button has a simple white icon I want to change it to a gradient colour

2

Answers


  1. I have the same problem too
    but for now
    if you wanna change the text color it works.
    like you convert image into pattern color by this code

    /*

    class gradiunTitle : UIButton  {
    
       override init(frame: CGRect) {
            super.init(frame: frame)
            setup()
          }
       required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            setup()
          }
       private func setup() {
           let gradient = getGradientLayer(bounds: self.bounds)
          self.setTitleColor(gradientColor(bounds: self.bounds, gradientLayer: gradient), for: .normal)
           self.tintColor = gradientColor(bounds: self.frame, gradientLayer: gradient)
          }
        func getGradientLayer(bounds : CGRect) -> CAGradientLayer{
        let gradient = CAGradientLayer()
        gradient.frame = bounds
        //order of gradient colors
        gradient.colors = [UIColor.red.cgColor,UIColor.blue.cgColor, UIColor.green.cgColor]
        gradient.startPoint = CGPoint(x: 0.0, y: 0.5)
        gradient.endPoint = CGPoint(x: 1.0, y: 0.5)
        return gradient
        }
        
        func gradientColor(bounds: CGRect, gradientLayer :CAGradientLayer) -> UIColor? {
        UIGraphicsBeginImageContext(gradientLayer.bounds.size)
        gradientLayer.render(in: UIGraphicsGetCurrentContext()!)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return UIColor(patternImage: image!)
        }
    }
    

    */

    Login or Signup to reply.
  2. I updated my answer according to Duncan C comment.

    You can modify your image before setting it to button.

    extension UIImage {
        
        func drawLinearGradient(colors: [CGColor], startingPoint: CGPoint, endPoint: CGPoint) -> UIImage? {
            let renderer = UIGraphicsImageRenderer(size: self.size)
            
            var shouldReturnNil = false
            let gradientImage = renderer.image { context in
                context.cgContext.translateBy(x: 0, y: self.size.height)
                context.cgContext.scaleBy(x: 1.0, y: -1.0)
    
                context.cgContext.setBlendMode(.normal)
                let rect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
    
                // Create gradient
                let colors = colors as CFArray
                let colorsSpace = CGColorSpaceCreateDeviceRGB()
                
                guard let gradient = CGGradient(colorsSpace: colorsSpace, colors: colors, locations: nil) else {
                    shouldReturnNil = true
                    return
                }
    
                // Apply gradient
                guard let cgImage = self.cgImage else {
                    shouldReturnNil = true
                    print("Couldn't get cgImage of UIImage.")
                    return
                }
                
                context.cgContext.clip(to: rect, mask: cgImage)
                context.cgContext.drawLinearGradient(
                    gradient,
                    start: endPoint,
                    end: startingPoint,
                    options: .init(rawValue: 0)
                )
            }
    
            return shouldReturnNil ? nil : gradientImage
        }
        
    }
    

    You can use it like that:

    guard let image = UIImage(named: "<your_image_name>") else { return }
    v.image = image.drawLinearGradient(
        colors: [UIColor.blue.cgColor, UIColor.red.cgColor],
        startingPoint: .init(x: image.size.width / 2, y: 0),
        endPoint: .init(x: image.size.width / 2, y: image.size.height)
    )
    button.setImage(gradientImage, for: .normal)
    

    This code produces result like this:

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search