How can I change image tintColor in iOS and WatchKit

16 Solutions Collect From Internet About “How can I change image tintColor in iOS and WatchKit”

iOS
For an iOS app, in Swift 3:

theImageView.image = theImageView.image!.withRenderingMode(.alwaysTemplate)
theImageView.tintColor = UIColor.red

Swift 2:

theImageView.image = theImageView.image!.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)
theImageView.tintColor = UIColor.redColor()

Meanwhile, the modern Objective-C solution is:

theImageView.image = [theImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[theImageView setTintColor:[UIColor redColor]];

Watchkit
In WatchKit for Apple Watch apps, you can set the tint color for a template image.

  1. You must add your image to an Asset Catalog in your WatchKit App, and set the image set to be rendered as a Template Image in the Attributes Inspector. Unlike for an iPhone app, you cannot set the template rendering in code in the WatchKit Extension at present.
  2. Set that image to be used in your WKInterfaceImage in interface builder for your app
  3. Create an IBOutlet in your WKInterfaceController for the WKInterfaceImage called ‘theImage’…

To then set the tint color in Swift 3:

theImage.setTintColor(UIColor.red)

Swift 2:

theImage.setTintColor(UIColor.redColor())

To then set the tint color in Objective-C:

[self.theImage setTintColor:[UIColor redColor]];

If you use a template image and do not apply a tint colour, the Global Tint for your WatchKit app will be applied. If you have not set a Global Tint, theImage will be tinted light blue by default when used as a template image.

Here’s a category that should do the trick

@interface UIImage(Overlay)
@end

@implementation UIImage(Overlay)

- (UIImage *)imageWithColor:(UIColor *)color1
{
        UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextTranslateCTM(context, 0, self.size.height);
        CGContextScaleCTM(context, 1.0, -1.0);
        CGContextSetBlendMode(context, kCGBlendModeNormal);
        CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
        CGContextClipToMask(context, rect, self.CGImage);
        [color1 setFill];
        CGContextFillRect(context, rect);
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return newImage;
}
@end

so you would do:

theImageView.image = [theImageView.image imageWithColor:[UIColor redColor]];

I had to do this in Swift using an extension.

I thought I’d share how I did it:

extension UIImage {
    func imageWithColor(color1: UIColor) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
        color1.setFill()

        let context = UIGraphicsGetCurrentContext() as CGContextRef
        CGContextTranslateCTM(context, 0, self.size.height)
        CGContextScaleCTM(context, 1.0, -1.0);
        CGContextSetBlendMode(context, CGBlendMode.Normal)

        let rect = CGRectMake(0, 0, self.size.width, self.size.height) as CGRect
        CGContextClipToMask(context, rect, self.CGImage)
        CGContextFillRect(context, rect)

        let newImage = UIGraphicsGetImageFromCurrentImageContext() as UIImage
        UIGraphicsEndImageContext()

        return newImage
    }
}

Usage:

theImageView.image = theImageView.image.imageWithColor(UIColor.redColor())

In storyboard and image Assets. you can change this two also:

Update the Render Mode to Template Image

Update the Render Mode to Template Image in Image Assets

Update the tint Color in Views.

Update the tint Color in Views in Views

Change tint of image (picture, classical image, photo) use that :

Function tintImage Swift 3 :

enter image description here
enter image description here

import UIKit

// MARK: - Extensions UIImage

public extension UIImage {

    /// Tint, Colorize image with given tint color
    /// This is similar to Photoshop's "Color" layer blend mode
    /// 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
    ///
    /// - Parameter TintColor: Tint color
    /// - Returns:  Tinted image
    public func tintImage(with fillColor: 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)
            fillColor.setFill()
            context.fill(rect)

            // mask by alpha values of original image
            context.setBlendMode(.destinationIn)
            context.draw(context.makeImage()!, in: rect)
        }
    }

    /// Tint pictogram with color
    /// Method work on single colors without fading, mainly for svg images
    ///
    /// - Parameter fillColor: TintColor: Tint color
    /// - Returns:             Tinted image
    public func tintPictogram(with 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!
    }
}
}

Change tint of image (SVG, unique color) use that with template image in asset :

Function tintPictogram Swift 3:

enter image description here
enter image description here

import UIKit

// MARK: - Extensions UIImage

public extension UIImage {

    /// Tint pictogram with color
    /// Method work on single colors without fading, mainly for svg images
    ///
    /// - Parameter fillColor: TintColor: Tint color
    /// - Returns:             Tinted image
    public func tintPictogram(with 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!
    }
}

With Swift

let commentImageView = UIImageView(frame: CGRectMake(100, 100, 100, 100))
commentImageView.image = UIImage(named: "myimage.png")!.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)
commentImageView.tintColor = UIColor.blackColor()
addSubview(commentImageView)

If anyone care a solution without UIImageView:

// (Swift 3)
extension UIImage {
    func tint(with color: UIColor) -> UIImage {
        var image = withRenderingMode(.alwaysTemplate)
        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        color.set()

        image.draw(in: CGRect(origin: .zero, size: size))
        image = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return image
    }
}

Try this

http://robots.thoughtbot.com/designing-for-ios-blending-modes

or

- (void)viewDidLoad
{
[super viewDidLoad];

UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 30, 300, 50)];
label.numberOfLines = 0;
label.font = [UIFont systemFontOfSize:13];
label.text = @"These checkmarks use the same gray checkmark image with a tintColor applied to the image view";
[self.view addSubview:label];

[self _createImageViewAtY:100 color:[UIColor purpleColor]];
}

- (void)_createImageViewAtY:(int)y color:(UIColor *)color {
UIImage *image = [[UIImage imageNamed:@"gray checkmark.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
CGRect frame = imageView.frame;
frame.origin.x = 100;
frame.origin.y = y;
imageView.frame = frame;

if (color)
    imageView.tintColor = color;

[self.view addSubview:imageView];
}

For swift 3 purposes

theImageView.image = theImageView.image!.withRenderingMode(.alwaysTemplate)
theImageView.tintColor = UIColor.red

Now i use this method based in Duncan Babbage response:

+ (UIImageView *) tintImageView: (UIImageView *)imageView withColor: (UIColor*) color{
    imageView.image = [imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
    [imageView setTintColor:color];
    return imageView;
}

You can use this in Swift 3 if you have an image to replace the clear button

func addTextfieldRightView(){

    let rightViewWidth:CGFloat = 30

    let viewMax = self.searchTxt.frame.height
    let buttonMax = self.searchTxt.frame.height - 16

    let buttonView = UIView(frame: CGRect(
        x: self.searchTxt.frame.width - rightViewWidth,
        y: 0,
        width: viewMax,
        height: viewMax))

    let myButton = UIButton(frame: CGRect(
        x: (viewMax - buttonMax) / 2,
        y: (viewMax - buttonMax) / 2,
        width: buttonMax,
        height: buttonMax))

    myButton.setImage(UIImage(named: "BlueClear")!, for: .normal)

    buttonView.addSubview(myButton)

    let clearPressed = UITapGestureRecognizer(target: self, action: #selector(SearchVC.clearPressed(sender:)))
    buttonView.isUserInteractionEnabled = true
    buttonView.addGestureRecognizer(clearPressed)

    myButton.addTarget(self, action: #selector(SearchVC.clearPressed(sender:)), for: .touchUpInside)

    self.searchTxt.rightView = buttonView
    self.searchTxt.rightViewMode = .whileEditing
}

Take benefit of Extension in Swift :-

extension UIImageView {
    func changeImageColor( color:UIColor) -> UIImage
    {
        image = image!.withRenderingMode(.alwaysTemplate)
        tintColor = color
        return image!
    }
}

   //Change color of logo 
   logoImage.image =  logoImage.changeImageColor(color: .red)

enter image description here

Subclass which can be used from code and Interface Builder as well:

@implementation TintedImageView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self setup];
    }
    return self;
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self setup];
    }
    return self;
}

-(void)setup {
    self.image = [self.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
}

@end

iOS

Solution for doing it from InterfaceBuilder, set templateImage param in keyPath and choose you tint color from IB

extension UIImageView {

// make template image with tint color
var templateImage: Bool {
    set {
        if newValue, let image = self.image {
            let newImage = image.withRenderingMode(.alwaysTemplate)
            self.image = newImage
        }
    } get {
        return false
    }
}

}

This is my UIImage extension and you can directly use changeTintColor function for an image.

extension UIImage {

    func changeTintColor(color: UIColor) -> UIImage {
        var newImage = self.withRenderingMode(.alwaysTemplate)
        UIGraphicsBeginImageContextWithOptions(self.size, false, newImage.scale)
        color.set()
        newImage.draw(in: CGRect(x: 0.0, y: 0.0, width: self.size.width, height: self.size.height))
        newImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return newImage
    }

    func changeColor(color: UIColor) -> UIImage {
        let backgroundSize = self.size
        UIGraphicsBeginImageContext(backgroundSize)
        guard let context = UIGraphicsGetCurrentContext() else {
            return self
        }
        var backgroundRect = CGRect()
        backgroundRect.size = backgroundSize
        backgroundRect.origin.x = 0
        backgroundRect.origin.y = 0

        var red: CGFloat = 0
        var green: CGFloat = 0
        var blue: CGFloat = 0
        var alpha: CGFloat = 0
        color.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
        context.setFillColor(red: red, green: green, blue: blue, alpha: alpha)
        context.translateBy(x: 0, y: backgroundSize.height)
        context.scaleBy(x: 1.0, y: -1.0)
        context.clip(to: CGRect(x: 0.0, y: 0.0, width: self.size.width, height: self.size.height),
                 mask: self.cgImage!)
        context.fill(backgroundRect)

        var imageRect = CGRect()
        imageRect.size = self.size
        imageRect.origin.x = (backgroundSize.width - self.size.width) / 2
        imageRect.origin.y = (backgroundSize.height - self.size.height) / 2

        context.setBlendMode(.multiply)
        context.draw(self.cgImage!, in: imageRect)

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

}

Example usage like this

let image = UIImage(named: "sample_image")
imageView.image = image.changeTintColor(color: UIColor.red)

And you can use change changeColor function to change the image color

Swift 3 version of extension answer from fuzz

func imageWithColor(color: UIColor) -> UIImage {
    UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
    color.setFill()

    let context = UIGraphicsGetCurrentContext()! as CGContext
    context.translateBy(x: 0, y: self.size.height)
    context.scaleBy(x: 1.0, y: -1.0);
    context.setBlendMode(.normal)

    let rect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height) as CGRect
    context.clip(to: rect, mask: self.cgImage!)
    context.fill(rect)

    let newImage = UIGraphicsGetImageFromCurrentImageContext()! as UIImage
    UIGraphicsEndImageContext()

    return newImage
}