如何在 iOS 和 WatchKit 中更改图像 tintColor
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19274789/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I change image tintColor in iOS and WatchKit
提问by chewy
I have an UIImageView called "theImageView", with UIImage in a single color (transparent background) just like the left black heart below. How can I change the tint color of this image programmatically in iOS 7 or above, as per the tint method used in the iOS 7+ Navigation Bar icons?
我有一个名为“theImageView”的 UIImageView,其中 UIImage 为单色(透明背景),就像下面的左黑心一样。根据 iOS 7+ 导航栏图标中使用的色调方法,如何在 iOS 7 或更高版本中以编程方式更改此图像的色调颜色?
Can this method also work in WatchKit for an Apple Watch app?
这种方法也可以在 Apple Watch 应用的 WatchKit 中使用吗?
回答by Duncan Babbage
iOS
For an iOS app, in Swift 3, 4 or 5:
iOS
对于 iOS 应用程序,在 Swift 3、4 或 5 中:
theImageView.image = theImageView.image?.withRenderingMode(.alwaysTemplate)
theImageView.tintColor = UIColor.red
For Swift 2:
对于 Swift 2:
theImageView.image = theImageView.image?.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)
theImageView.tintColor = UIColor.redColor()
Meanwhile, the modern Objective-C solution is:
同时,现代的 Objective-C 解决方案是:
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.
Watchkit
在 Apple Watch 应用程序的 WatchKit 中,您可以设置模板图像的色调颜色。
- 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'...
- 您必须将图像添加到 WatchKit 应用程序中的资产目录,并将图像集设置为在属性检查器中呈现为模板图像。与 iPhone 应用程序不同,目前您无法在 WatchKit 扩展中的代码中设置模板渲染。
- 将该图像设置为在您的应用程序的界面构建器中的 WKInterfaceImage 中使用
- 在 WKInterfaceController 中为名为“theImage”的 WKInterfaceImage 创建一个 IBOutlet...
To then set the tint color in Swift 3 or 4:
然后在 Swift 3 或 4 中设置色调颜色:
theImage.setTintColor(UIColor.red)
Swift 2:
斯威夫特 2:
theImage.setTintColor(UIColor.redColor())
To then set the tint color in Objective-C:
然后在 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.
如果您使用模板图像并且不应用色调颜色,则将应用 WatchKit 应用程序的全局色调。如果您没有设置全局色调,theImage
当用作模板图像时默认会被染成淡蓝色。
回答by iamamused
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]];
回答by fulvio
I had to do this in Swift using an extension
.
我必须在 Swift 中使用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())
theImageView.image = theImageView.image.imageWithColor(UIColor.redColor())
Swift 4
斯威夫特 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)
theImageView.image = theImageView.image?.imageWithColor(color1: UIColor.red)
回答by JerryZhou
回答by YannSteph
Swift 4
斯威夫特 4
Change tint of UIImage SVG / PDF, that work for image with unique color:
更改UIImage SVG / PDF 的色调,适用于具有独特颜色的图像:
import Foundation
// MARK: - UIImage extensions
public extension UIImage {
//
/// Tint Image
///
/// - Parameter fillColor: UIColor
/// - Returns: Image with tint color
func tint(with fillColor: UIColor) -> UIImage? {
let image = withRenderingMode(.alwaysTemplate)
UIGraphicsBeginImageContextWithOptions(size, false, scale)
fillColor.set()
image.draw(in: CGRect(origin: .zero, size: size))
guard let imageColored = UIGraphicsGetImageFromCurrentImageContext() else {
return nil
}
UIGraphicsEndImageContext()
return imageColored
}
}
Change tint of UIImageView, that work for image with unique color:
更改UIImageView 的色调,适用于具有独特颜色的图像:
let imageView = UIImageView(frame: CGRect(x: 50, y: 50, width: 50, height: 50))
imageView.image = UIImage(named: "hello.png")!.withRenderingMode(.alwaysTemplate)
imageView.tintColor = .yellow
Change tint of UIImagefor picture, use that :
变更色彩的UIImage的图片,使用:
import Foundation
// 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)
}
}
/// 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!
}
}
回答by Puttin
If anyone care a solution without UIImageView
:
如果有人关心没有解决方案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
}
}
回答by Esqarrouth
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)
回答by yazh
Try this
尝试这个
http://robots.thoughtbot.com/designing-for-ios-blending-modes
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];
}
回答by DairySeeker
For swift 3 purposes
快速 3 目的
theImageView.image = theImageView.image!.withRenderingMode(.alwaysTemplate)
theImageView.tintColor = UIColor.red
theImageView.image = theImageView.image!.withRenderingMode(.alwaysTemplate)
theImageView.tintColor = UIColor.red
回答by Hakob
iOS
IOS
Solution for doing it from Interface Builder, set templateImage param in keyPathand choose your tint color from IB
从 Interface Builder 执行此操作的解决方案,在 keyPath 中设置 templateImage 参数并从 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
}
}
}
}