ios - guidelines - iphone icons
Modifique UIImage renderingMode desde un archivo storyboard/xib (12)
¿Es posible modificar el renderingMode
de UIImage
desde un storyboard o editor xib?
El objetivo es aplicar tintColor
al objeto particular UIImageView
.
Así es cómo puedes hacerlo en archivos .xib o guiones gráficos:
Crea 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
Luego, en el Inspector de identidad en el archivo xib, agregue un atributo de tiempo de ejecución:
En la configuración de iOS 9, la propiedad tintColor
en Interface Builder sigue fallando.
Tenga en cuenta que una solución de trabajo además de escribir líneas que modifican directamente las propiedades de ImageView
es establecer Renderizar como: Imagen de plantilla en el catálogo de activos, y llamar, por ejemplo:
[[UIImageView appearanceWhenContainedInInstancesOfClasses:@[[MyView class]]] setTintColor:[UIColor whiteColor]];
Es muy fácil de arreglar
Simplemente crea la clase UIImageViewPDF y úsalo en tu 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
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
}
}
Forma simple de establecerse 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
La configuración de ImageView RenderingMode para usar el color del 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 Guión gráfico.
No puede establecer renderingMode
ni desde el storyboard
ni desde xib
. Podía acceder programáticamente.
ex:
UIImage *unSeletedImage = [UIImage imageNamed:@"UnSelected.png"];
selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
Otra solución es crear una subclase UIImageView
:
final class TemplateImageView: UIImageView {
override func awakeFromNib() {
super.awakeFromNib()
guard let oldImage = image else { return }
image = nil
image = oldImage.withRenderingMode(.alwaysTemplate)
}
}
Luego, simplemente configure la clase en Interface Builder para TemplateImageView
.
Puede configurar el modo de representación de imágenes no en el archivo .xib
, sino en una biblioteca .xcassets
.
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. Encuentre el atributo ''Renderizar'' y configúrelo como ''plantilla''.
Después de configurar el modo de renderizado de una imagen, puede agregar un color de tinte a UIImageView
en un archivo .xib
o .storyboard
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 construcción de interfaz, pero en casi todos los casos (que he encontrado) este es el comportamiento que desea.
Algunas cosas a tener en cuenta:
- El color de la imagen no parece haber cambiado en el constructor de interfaz (a partir de Xcode 6.1.1), pero funcionará cuando se ejecute la aplicación.
- He experimentado algunos problemas con esta característica y en algunas situaciones he tenido que eliminar y volver a agregar
UIImageView
. No he investigado eso profundamente. - Esto también funciona muy bien en otros
UIKitComponents
, como las imágenes enUIButton
yUIBarButtonItem
. - Si tiene un montón de imágenes blancas que son invisibles en su biblioteca de activos, convertirlas en imágenes negras / transparentes y cambiar el modo de renderización mejorará su vida hasta 10 veces.
Puede corregir problemas .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 por unos 4 o 5 años.
Si crea un IBOutlet, puede cambiarlo en su método awakeFromNib como ese ...
self.myImageView.image = [self.myImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
Si bien la respuesta de @Moby es más correcta, esto podría ser más sucinto.
Usar el modo de representación de plantilla con UIImageView en un guión gráfico o xib es muy complicado, tanto en iOS 7 como en iOS 8.
En iOS 7
El UIImage no está decodificado correctamente del storyboard / xib. Si inspecciona la propiedad imageView.image.renderingMode
en el método viewDidLoad
, observará que siempre es UIImageRenderingModeAutomatic
, incluso si lo configura en Renderizar como imagen de plantilla en su archivo xcassets.
Para solucionarlo, debe configurar manualmente el modo de representación:
self.imageView.image = [self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
En iOS 8
El UIImage está decodificado correctamente y su propiedad renderingMode
refleja lo que se eligió en el archivo xcassets, pero la imagen no está teñida.
Para solucionarlo, tiene dos opciones:
- Establezca la propiedad
tintColor
en los atributos de tiempo de ejecución definidos por el usuario en lugar del panel del inspector de atributos.
o
- Restablecer manualmente el tintColor:
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, simplemente haciendo self.imageView.tintColor = self.imageView.tintColor;
es suficiente, pero esto ya no funciona si está compilando con Xcode 6.3)
Conclusión
Si necesita admitir iOS 7 e iOS 8, necesitará ambas soluciones. Si solo tiene que admitir iOS 8, solo se necesita una solución.