¿Es posible modificar un UIImage
's renderingMode
de un editor de guión gráfico o xib?
El objetivo es aplicar tintColor
al UIImageView
objeto en particular .
¿Es posible modificar un UIImage
's renderingMode
de un editor de guión gráfico o xib?
El objetivo es aplicar tintColor
al UIImageView
objeto en particular .
Respuestas:
Así es como puede hacerlo en archivos .xib o storyboard:
(Obj-C) Cree una categoría en UIImageView
:
@interface UIImageView (Utils)
- (void)setImageRenderingMode:(UIImageRenderingMode)renderMode;
@end
@implementation UIImageView (Utils)
- (void)setImageRenderingMode:(UIImageRenderingMode)renderMode
{
NSAssert(self.image, @"Image must be set before setting rendering mode");
self.image = [self.image imageWithRenderingMode:renderMode];
}
@end
(Swift 4) Cree una extensión para UIImageView
:
extension UIImageView {
func setImageRenderingMode(_ renderMode: UIImage.RenderingMode) {
assert(image != nil, "Image must be set before setting rendering mode")
// AlwaysOriginal as an example
image = image?.withRenderingMode(.alwaysOriginal)
}
}
Luego, en el Inspector de identidad en el archivo xib, agregue un atributo de tiempo de ejecución:
Puede establecer el modo de representación de imágenes no en el .xib
archivo, sino en una .xcassets
biblioteca.
Después de agregar una imagen a una biblioteca de activos, seleccione la imagen y abra el inspector de atributos en el lado derecho de Xcode. Busque el atributo 'Renderizar como' y establézcalo en 'plantilla'.
Después de configurar el modo de representación de una imagen, se puede añadir un color de tinte a la UIImageView
de una .xib
o.storyboard
archivo para ajustar el color de la imagen.
Esto establece la propiedad en la imagen donde sea que se use en lugar de solo en un archivo de generador de interfaz, pero en casi todos los casos (que he encontrado) este es el comportamiento que desea.
Algunas cosas a tener en cuenta:
UIImageView
. No he mirado tan profundamente.UIKitComponents
imágenes como UIButton
las de y UIBarButtonItem
.UIImageView
, por lo que el color de tinte no siempre se muestra al ejecutar la aplicación.
Usar el modo de renderizado de plantillas con UIImageView en un guión gráfico o xib tiene muchos errores, tanto en iOS 7 como en iOS 8.
El UIImage no se decodifica correctamente desde el guión gráfico / xib. Si inspecciona la imageView.image.renderingMode
propiedad en el viewDidLoad
método, notará que siempre lo es UIImageRenderingModeAutomatic
, incluso si lo establece en Renderizar como imagen de plantilla en su archivo xcassets.
Para solucionarlo, debe configurar manualmente el modo de renderizado:
self.imageView.image = [self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
El UIImage está correctamente decodificado y su renderingMode
propiedad refleja lo que se eligió en el archivo xcassets, pero la imagen no está teñida.
Para solucionarlo, tiene dos opciones:
tintColor
propiedad en Atributos de tiempo de ejecución definidos por el usuario en lugar del panel del inspector de atributos.o
UIColor *tintColor = self.imageView.tintColor;
self.imageView.tintColor = nil;
self.imageView.tintColor = tintColor;
Puede elegir su opción preferida, ambos matizan correctamente la imagen.
(Si está compilando con Xcode 6.2, solo hacerlo self.imageView.tintColor = self.imageView.tintColor;
es suficiente, pero esto ya no funciona si está compilando con Xcode 6.3)
Si necesita admitir tanto iOS 7 como iOS 8, necesitará ambas soluciones. Si solo tiene que admitir iOS 8, solo se necesita una solución alternativa.
La configuración de imageView RenderingMode para usar el color de tinte en el guión gráfico se puede reducir a una sola línea:
[self.imageView setImage:[self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]];
Luego, la imagen y el color del tinte se pueden configurar en el Storyboard.
Puede solucionar problemas de .xib con una extensión:
import UIKit
// fixing Bug in XCode
// http://openradar.appspot.com/18448072
extension UIImageView {
override open func awakeFromNib() {
super.awakeFromNib()
self.tintColorDidChange()
}
}
Fuente: https://gist.github.com/buechner/3b97000a6570a2bfbc99c005cb010bac
Increíble, este error ha existido durante unos 4-5 años.
No puede establecer renderingMode
ni desde storyboard
ni xib
. Podría acceder mediante programación.
ex:
UIImage *unSeletedImage = [UIImage imageNamed:@"UnSelected.png"];
selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
UIImage *selectedImage = [unSeletedImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
Establezca tintColor & Class en Storyboard.
//
// TintColoredImageView.swift
// TintColoredImageView
//
// Created by Dmitry Utmanov on 14/07/16.
// Copyright © 2016 Dmitry Utmanov. All rights reserved.
//
import UIKit
@IBDesignable class TintColoredImageView: UIImageView {
override var image: UIImage? {
didSet {
let _tintColor = self.tintColor
self.tintColor = nil
self.tintColor = _tintColor
}
}
override init(frame: CGRect) {
super.init(frame: frame)
initialize()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
initialize()
}
override init(image: UIImage?) {
super.init(image: image)
initialize()
}
override init(image: UIImage?, highlightedImage: UIImage?) {
super.init(image: image, highlightedImage: highlightedImage)
initialize()
}
func initialize() {
let _tintColor = self.tintColor
self.tintColor = nil
self.tintColor = _tintColor
}
}
Es muy facil de arreglar
Simplemente cree la clase UIImageViewPDF y úsela en su guión gráfico
IB_DESIGNABLE
@interface UIImageViewPDF : UIImageView
@end
@implementation UIImageViewPDF
- (void) didMoveToSuperview
{
[super didMoveToSuperview];
self.image = [self.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
id color = self.tintColor;
self.tintColor = color;
}
@end
Otra solución es crear una UIImageView
subclase:
final class TemplateImageView: UIImageView {
override func awakeFromNib() {
super.awakeFromNib()
guard let oldImage = image else { return }
image = nil
image = oldImage.withRenderingMode(.alwaysTemplate)
}
}
Luego, configure la clase en Interface Builder en TemplateImageView
.
Forma sencilla de configurar desde Storyboard:
@IBDesignable
public class CustomImageView: UIImageView {
@IBInspectable var alwaysTemplate: Bool = false {
didSet {
if alwaysTemplate {
self.image = self.image?.withRenderingMode(.alwaysTemplate)
} else {
self.image = self.image?.withRenderingMode(.alwaysOriginal)
}
}
}
}
Funciona bien en iOS 10 y Swift 3
En iOS 9, la configuración de la tintColor
propiedad en Interface Builder todavía tiene errores.
Tenga en cuenta que una solución de trabajo además de escribir líneas que modifican directamente las ImageView
propiedades es establecer Renderizar como: Imagen de plantilla en el catálogo de activos y llamar, por ejemplo:
[[UIImageView appearanceWhenContainedInInstancesOfClasses:@[[MyView class]]] setTintColor:[UIColor whiteColor]];
Si crea un IBOutlet, puede cambiarlo en su método awakeFromNib así ...
self.myImageView.image = [self.myImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
Si bien la respuesta de @ Moby es más correcta, esto podría ser más conciso.
¡Loco, este error todavía está en iOS 12.1! Para guiones gráficos / xibs: agregar una etiqueta a UIImageView puede ser una solución rápida.
Rápido 4.2
view.viewWithTag(1)?.tintColorDidChange()
extension UIImageView {
@IBInspectable var renderModeTemplate : Bool {
get{
return image?.renderingMode == .alwaysTemplate
}
set{
image = image?.withRenderingMode(newValue ? .alwaysTemplate:.alwaysOriginal)
}
}
}
En el guión gráfico, seleccione UIImageView y seleccione el inspector, establezca la propiedad renderModeTemplate
= On
En el guión gráfico
Como Rudolf también mencionó anteriormente , definiría una clase simple, como esta:
import UIKit
@IBDesignable class TintImage: UIImageView{
override func layoutSubviews() {
super.layoutSubviews()
image = image?.withRenderingMode(.alwaysTemplate)
}
}
Después de esta definición, simplemente agregue una Vista de imagen al guión gráfico y seleccione su clase personalizada como TintImage
. Esto activará la selección "Tinte" en el guión gráfico.