Change color png in buttons - ios

I have a set of icons that I created that are transparent white PNG:

enter image description here

And what I would like to do is tweak them to other colors. For example, blue, gray, etc.

I noticed that "clicked / tapped" automatically changes to gray. Therefore, I assume that I can change this gray color to something that I like either with the tap or with its normal state:

enter image description here

What would be the best way to achieve this?

+79
ios swift
Nov 27 '14 at 4:38
source share
9 answers

The following code sets the hue color for the normal state of the button:

For Swift 4 and later:

let origImage = UIImage(named: "imageName") let tintedImage = origImage?.withRenderingMode(.alwaysTemplate) btn.setImage(tintedImage, for: .normal) btn.tintColor = .red 

You can change the color of the hue according to your needs when changing the state of the button.




Old versions

For Swift 3:

 let origImage = UIImage(named: "imageName") let tintedImage = origImage?.withRenderingMode(.alwaysTemplate) btn.setImage(tintedImage, forState: .normal) btn.tintColor = .redColor 

For Swift 2: see Change History.

+193
Nov 27 '14 at 5:36 on
source share

In iOS 7, the tintColor property was introduced for views (including UIImageView). However, you also need to set the rendering type to UIImage so that it has any effect.

 UIImage *originalImage = [UIImage imageNamed:@"image.png"]; UIImage *tintedImage = [originalImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; UIImageView *imageView = [[UIImageView alloc] initWithImage:tintedImage]; imageView.tintColor = [UIColor grayColor]; [self.view addSubview:imageView]; 

This will produce the result that you execute in the default state.

+13
Nov 27 '14 at 5:20
source share

You can use this extension:

 import UIKit extension CGContext { func fill(_ rect: CGRect, with mask: CGImage, using color: CGColor) { saveGState() defer { restoreGState() } translateBy(x: 0.0, y: rect.size.height) scaleBy(x: 1.0, y: -1.0) setBlendMode(.normal) clip(to: rect, mask: mask) setFillColor(color) fill(rect) } } extension UIImage { func filled(with color: UIColor) -> UIImage { let rect = CGRect(origin: .zero, size: self.size) guard let mask = self.cgImage else { return self } if #available(iOS 10.0, *) { let rendererFormat = UIGraphicsImageRendererFormat() rendererFormat.scale = self.scale let renderer = UIGraphicsImageRenderer(size: rect.size, format: rendererFormat) return renderer.image { context in context.cgContext.fill(rect, with: mask, using: color.cgColor) } } else { UIGraphicsBeginImageContextWithOptions(rect.size, false, self.scale) defer { UIGraphicsEndImageContext() } guard let context = UIGraphicsGetCurrentContext() else { return self } context.fill(rect, with: mask, using: color.cgColor) return UIGraphicsGetImageFromCurrentImageContext() ?? self } } } 
+9
Oct 21 '16 at 13:25
source share

To change the hue of an image ( select , classic image , photo ):

Image example: enter image description here enter image description here

Swift 2

 public extension UIImage { /** Tint, Colorize image with given tint color<br><br> This is similar to Photoshop "Color" layer blend mode<br><br> This is perfect for non-greyscale source images, and images that have both highlights and shadows that should be preserved<br><br> white will stay white and black will stay black as the lightness of the image is preserved<br><br> <img src="http://yannickstephan.com/easyhelper/tint1.png" height="70" width="120"/> **To** <img src="http://yannickstephan.com/easyhelper/tint2.png" height="70" width="120"/> - parameter tintColor: UIColor - returns: UIImage */ public func tintPhoto(tintColor: UIColor) -> UIImage { return modifiedImage { context, rect in // draw black background - workaround to preserve color of partially transparent pixels CGContextSetBlendMode(context, .Normal) UIColor.blackColor().setFill() CGContextFillRect(context, rect) // draw original image CGContextSetBlendMode(context, .Normal) CGContextDrawImage(context, rect, self.CGImage) // tint image (loosing alpha) - the luminosity of the original image is preserved CGContextSetBlendMode(context, .Color) tintColor.setFill() CGContextFillRect(context, rect) // mask by alpha values of original image CGContextSetBlendMode(context, .DestinationIn) CGContextDrawImage(context, rect, self.CGImage) } } /** Tint Picto to color - parameter fillColor: UIColor - returns: UIImage */ public func tintPicto(fillColor: UIColor) -> UIImage { return modifiedImage { context, rect in // draw tint color CGContextSetBlendMode(context, .Normal) fillColor.setFill() CGContextFillRect(context, rect) // mask by alpha values of original image CGContextSetBlendMode(context, .DestinationIn) CGContextDrawImage(context, rect, self.CGImage) } } /** Modified Image Context, apply modification on image - parameter draw: (CGContext, CGRect) -> ()) - returns: UIImage */ private func modifiedImage(@noescape draw: (CGContext, CGRect) -> ()) -> UIImage { // using scale correctly preserves retina images UIGraphicsBeginImageContextWithOptions(size, false, scale) let context: CGContext! = UIGraphicsGetCurrentContext() assert(context != nil) // correctly rotate image CGContextTranslateCTM(context, 0, size.height); CGContextScaleCTM(context, 1.0, -1.0); let rect = CGRectMake(0.0, 0.0, size.width, size.height) draw(context, rect) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return image } } 

UPD

Swift 3

 extension UIImage { /** Tint, Colorize image with given tint color<br><br> This is similar to Photoshop "Color" layer blend mode<br><br> This is perfect for non-greyscale source images, and images that have both highlights and shadows that should be preserved<br><br> white will stay white and black will stay black as the lightness of the image is preserved<br><br> <img src="http://yannickstephan.com/easyhelper/tint1.png" height="70" width="120"/> **To** <img src="http://yannickstephan.com/easyhelper/tint2.png" height="70" width="120"/> - parameter tintColor: UIColor - returns: UIImage */ func tintPhoto(_ tintColor: UIColor) -> UIImage { return modifiedImage { context, rect in // draw black background - workaround to preserve color of partially transparent pixels context.setBlendMode(.normal) UIColor.black.setFill() context.fill(rect) // draw original image context.setBlendMode(.normal) context.draw(cgImage!, in: rect) // tint image (loosing alpha) - the luminosity of the original image is preserved context.setBlendMode(.color) tintColor.setFill() context.fill(rect) // mask by alpha values of original image context.setBlendMode(.destinationIn) context.draw(context.makeImage()!, in: rect) } } /** Tint Picto to color - parameter fillColor: UIColor - returns: UIImage */ func tintPicto(_ fillColor: UIColor) -> UIImage { return modifiedImage { context, rect in // draw tint color context.setBlendMode(.normal) fillColor.setFill() context.fill(rect) // mask by alpha values of original image context.setBlendMode(.destinationIn) context.draw(cgImage!, in: rect) } } /** Modified Image Context, apply modification on image - parameter draw: (CGContext, CGRect) -> ()) - returns: UIImage */ fileprivate func modifiedImage(_ draw: (CGContext, CGRect) -> ()) -> UIImage { // using scale correctly preserves retina images UIGraphicsBeginImageContextWithOptions(size, false, scale) let context: CGContext! = UIGraphicsGetCurrentContext() assert(context != nil) // correctly rotate image context.translateBy(x: 0, y: size.height) context.scaleBy(x: 1.0, y: -1.0) let rect = CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height) draw(context, rect) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return image! } } 
+8
Dec 31 '15 at 14:23
source share

If you use asset catalogs, you can set the image object itself for rendering in template mode. After that, you can set the tintColor buttons in the Interface Builder (or in the code), and it should accept.

+4
Feb 15 '17 at 14:19
source share

If you are setting an image for a button, simply go to the attribute inspector and change the button type to system. Then set the image and change the color of the hue. The color of the image will change. If this does not happen, check the button type.

+4
12 Oct '17 at 12:04 on
source share

Swift 4

  let origImage = UIImage(named: "check") let tintedImage = origImage?.withRenderingMode(.alwaysTemplate) buttons[0].setImage(tintedImage, for: .normal) buttons[0].tintColor = .red 
+4
Feb 04 '18 at 17:46
source share

If you use asset catalogs, you can set the image object itself for rendering in template mode. After that, you can set the tintColor buttons in the Interface Builder (or in the code), and this should happen.

+2
Nov 26 '18 at 8:22
source share

Swift 4 and 4.2

 let img = UIImage.init(named: "buttonName")?.withRenderingMode(UIImageRenderingMode.alwaysTemplate) btn.setImage(img, for: .normal) btn.tintColor = .gray 

enter image description here

-one
Feb 21 '19 at 10:34
source share



All Articles