¿Cómo puedo cambiar la imagen tintColor en iOS y WatchKit?

Tengo un UIImageView llamado “theImageView”, con UIImage en un solo color (fondo transparente) al igual que el corazón negro izquierdo a continuación. ¿Cómo puedo cambiar el color del tinte de esta imagen mediante progtwigción en iOS 7 o superior, según el método de tinte utilizado en los icons de la barra de navegación iOS 7+?

¿Este método también puede funcionar en WatchKit para una aplicación Apple Watch?

enter image description here

iOS
Para una aplicación iOS, en Swift 3 o 4:

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

Swift 2:

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

Mientras tanto, la solución moderna de Objective-C es:

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

Watchkit
En las aplicaciones WatchKit para Apple Watch, puede establecer el color del tinte para una imagen de plantilla .

  1. Debe agregar su imagen a un catálogo de activos en su aplicación WatchKit, y establecer el conjunto de imágenes para que se represente como una imagen de plantilla en el inspector de atributos. A diferencia de una aplicación de iPhone, no puede establecer la representación de la plantilla en el código en la Extensión WatchKit en este momento.
  2. Establezca esa imagen para usar en su WKInterfaceImage en el constructor de interfaz para su aplicación
  3. Cree un IBOutlet en su WKInterfaceController para WKInterfaceImage llamado ‘theImage’ …

Para establecer el color del tinte en Swift 3 o 4:

 theImage.setTintColor(UIColor.red) 

Swift 2:

 theImage.setTintColor(UIColor.redColor()) 

Para establecer el color del tinte en Objective-C:

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

Si usa una imagen de plantilla y no aplica un color de tinte, se aplicará el tinte global para su aplicación WatchKit. Si no ha configurado un Tono global, la theImage se theImage azul claro de forma predeterminada cuando se utiliza como imagen de plantilla.

Aquí hay una categoría que debería hacer el truco

 @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 

entonces lo harías:

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

Tenía que hacer esto en Swift usando una extension .

Pensé en compartir cómo lo hice

 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 } } 

Uso:

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! } } 

Uso:

theImageView.image = theImageView.image?.imageWithColor(color1: UIColor.red)

En el guión gráfico y la imagen de los activos. puedes cambiar estos dos también:

Actualice el modo Renderizar a la imagen de la plantilla

Actualice el modo Renderizar a la imagen de la plantilla en los elementos de imagen

Actualice el color del tinte en Vistas.

Actualice el color del tinte en Vistas en Vistas

Cambiar el tinte de la imagen ( imagen , imagen clásica , foto ) use eso:

Función 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

/// 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! } } }

Cambiar el tinte de la imagen ( SVG , color único ) usar eso con la imagen de la plantilla en el activo :

Función 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! } } 

Si a alguien le importa una solución sin 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 } } 

Con 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) 

Prueba esto

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

o

 - (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]; } 

Para rápidos 3 propósitos

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

Aproveche la extensión de 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

iOS

Solución para hacerlo desde InterfaceBuilder, establecer templateImage param en keyPath y elegir el color del tinte de 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 } } 

}

Ahora uso este método basado en la respuesta de Duncan Babbage:

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

Puedes usar esto en Swift 3 si tienes una imagen para reemplazar el botón borrar

 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 } 

Subclase que se puede usar también desde el código y el 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 

Esta es mi extensión UIImage y puedes usar directamente la función changeTintColor para una imagen.

 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! } } 

Ejemplo de uso como este

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

Y puede usar cambiar la función changeColor para cambiar el color de la imagen

Versión de Swift 3 de la respuesta de extensión de 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 } 

Para teñir la imagen de un UIButton

  let image1 = "ic_shopping_cart_empty" btn_Basket.setImage(UIImage(named: image1)?.withRenderingMode(.alwaysTemplate), for: .normal) btn_Basket.setImage(UIImage(named: image1)?.withRenderingMode(.alwaysTemplate), for: .selected) btn_Basket.imageView?.tintColor = UIColor(UIColor.Red) 

profileImageView.image = theImageView.image! .withRenderingMode (.alwaysTemplate)
profileImageView.tintColor = UIColor.green

O

Primero seleccione Imagen particular en el elemento de imagen y luego seleccione enrojecido como Plantilla en lugar de Predeterminado y después de esa línea de escritura. profileImageView.tintColor = UIColor.green