如何更改iOS和WatchKit中的图像tintColor
我有一个名为“theImageView”的UIImageView,UIImage在单一颜色(透明背景),就像下面的左边的黑色心脏一样。 如何根据iOS 7+导航栏图标中使用的色调方法,在iOS 7或更高版本中以编程方式更改此图像的色调颜色?
此方法也可以在WatchKit中使用Apple Watch应用程序吗?
iOS版
对于iOS应用程序,在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()
同时,现代的Objective-C解决scheme是:
theImageView.image = [theImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; [theImageView setTintColor:[UIColor redColor]];
Watchkit
在WatchKit for Apple Watch应用程序中,您可以为模板图像设置色调颜色 。
- 您必须将图像添加到WatchKit应用程序中的资源目录,并将图像集设置为“属性”检查器中的模板图像。 与iPhone应用程序不同的是,您目前无法在WatchKit Extension中的代码中设置模板渲染。
- 将该图像设置为在您的应用的界面构build器的WKInterfaceImage中使用
- 在WKInterfaceImage的WKInterfaceController中创build一个名为'theImage'的IBOutlet …
然后在Swift 3中设置色彩的颜色:
theImage.setTintColor(UIColor.red)
Swift 2:
theImage.setTintColor(UIColor.redColor())
然后在Objective-C中设置色调的颜色:
[self.theImage setTintColor:[UIColor redColor]];
如果您使用模板图像而不应用色调颜色,则适用于WatchKit应用程序的全局色调。 如果尚未设置全局色调,则在用作模板图像时,默认情况下, theImage
将默认为浅蓝色。
这是一个应该做的伎俩
@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
所以你会这样做:
theImageView.image = [theImageView.image imageWithColor:[UIColor redColor]];
我不得不在Swift中使用extension
来做到这一点。
我以为我会分享我是如何做到的:
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 } }
用法:
theImageView.image = theImageView.image.imageWithColor(UIColor.redColor())
在故事板和图像资产。 你也可以改变这两个:
将渲染模式更新为模板图像
更新视图中的色调颜色。
改变图像的色调( 图片 , 经典图片 , 照片 )使用:
函数tintImage Swift 3:
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! } } }
在资产中改变使用模板图像的图像 色彩 ( SVG , 独特的颜色 ):
functiontintPictogram Swift 3:
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! } }
随着斯威夫特
let commentImageView = UIImageView(frame: CGRectMake(100, 100, 100, 100)) commentImageView.image = UIImage(named: "myimage.png")!.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate) commentImageView.tintColor = UIColor.blackColor() addSubview(commentImageView)
如果有人关心没有UIImageView
的解决scheme:
// (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 } }
尝试这个
http://robots.thoughtbot.com/designing-for-ios-blending-modes
要么
- (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]; }
为了迅速3目的
theImageView.image = theImageView.image!.withRenderingMode(.alwaysTemplate) theImageView.tintColor = UIColor.red
现在我用这个方法在Duncan Babbage的基础上做出回应:
+ (UIImageView *) tintImageView: (UIImageView *)imageView withColor: (UIColor*) color{ imageView.image = [imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; [imageView setTintColor:color]; return imageView; }
如果你有一个图像来replace清除button,你可以在Swift 3中使用它
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 }
利用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)
可以从代码和Interface Builder中使用的子类:
@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版
解决scheme从InterfaceBuilder中执行, 在keyPath中设置templateImage参数,并从IB中select色调颜色
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 } }
}
这是我的UIImage扩展,您可以直接使用changeTintColorfunction的图像。
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! } }
使用示例如下
let image = UIImage(named: "sample_image") imageView.image = image.changeTintColor(color: UIColor.red)
您可以使用更改changeColor
function来更改图像的颜色
Swift 3
从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 }