How can I change image tintColor in iOS and WatchKit
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]];
iOS
For an iOS app, in Swift 3, 4 or 5:
theImageView.image = theImageView.image?.withRenderingMode(.alwaysTemplate)
theImageView.tintColor = UIColor.red
For 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.
- 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.
- Set that image to be used in your WKInterfaceImage in interface builder for your app
- Create an IBOutlet in your WKInterfaceController for the WKInterfaceImage called 'theImage'...
To then set the tint color in Swift 3 or 4:
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.
In storyboard and image Assets. you can change this two also:
Update the Render Mode to Template Image
Update the tint Color in Views.
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())
Swift 4
extension UIImage {
func imageWithColor(color1: UIColor) -> UIImage {
UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
color1.setFill()
let context = UIGraphicsGetCurrentContext()
context?.translateBy(x: 0, y: self.size.height)
context?.scaleBy(x: 1.0, y: -1.0)
context?.setBlendMode(CGBlendMode.normal)
let rect = CGRect(origin: .zero, size: CGSize(width: self.size.width, height: self.size.height))
context?.clip(to: rect, mask: self.cgImage!)
context?.fill(rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
}
Usage:
theImageView.image = theImageView.image?.imageWithColor(color1: UIColor.red)