¿Por qué los iconos no quieren cambiar de color? Introducción a tintColor
Imagina: estás escribiendo una aplicación para iPhone o Apple Watch. El diseñador te envió un hermoso conjunto de iconos negros. Los colocas en un UIImageView, aplicas tintColor y... no pasa nada. El icono sigue siendo negro, como antes. ¿Te suena? Esta pregunta es una de las más frecuentes en Stack Overflow, y hoy la analizaremos a nivel molecular.
El problema es que tintColor solo funciona con imágenes que están en modo Template Image. Si simplemente estableces un color para una imagen normal (Original Image), el sistema ignorará tu solicitud. Aprendamos a controlar este mecanismo.
¿Qué es Template Image y para qué sirve?
En iOS y WatchKit, todas las imágenes se dividen en dos tipos:
- Original Image — una imagen normal con todos sus colores. No se puede colorear mediante
tintColor. - Template Image — una imagen donde solo se considera el canal alfa (transparencia) como color. Todos los píxeles visibles se vuelven "vacíos": están listos para aceptar cualquier color que les asignes.
Cuando aplicas tintColor a una Template Image, el sistema rellena todas las áreas opacas con el color especificado. Esto es ideal para iconos, botones y elementos de interfaz que deben adaptarse al tema de la aplicación.
Formas de cambiar tintColor en iOS (Swift)
1. La forma más sencilla: a través de Interface Builder
Si trabajas en Storyboard o XIB:
- Selecciona tu
UIImageViewoUIButton. - En el inspector de atributos, busca el campo Render Mode.
- Establécelo en Template Image.
- Ahora la propiedad Tint en el inspector funcionará.
2. Forma programática: código en Swift
Así es como se hace correctamente:
// Cargamos la imagenlet originalImage = UIImage(named: "myIcon")
// Convertimos a Templatelet templateImage = originalImage?.withRenderingMode(.alwaysTemplate)
// Aplicamos a UIImageViewimageView.image = templateImageimageView.tintColor = UIColor.systemBlueEl método clave es withRenderingMode(.alwaysTemplate). Le dice al sistema: "No prestes atención a los colores originales, yo mismo los pintaré todos".
3. Cambio de color para UIButton
Para los botones, el proceso es similar, pero hay un matiz:
button.setImage(UIImage(named: "heart")?.withRenderingMode(.alwaysTemplate), for: .normal)button.tintColor = UIColor.redObserva: aplicamos withRenderingMode directamente a la imagen que configuramos para el botón.
Particularidades de tintColor en WatchKit
El desarrollo para Apple Watch tiene sus limitaciones. En WatchKit no hay UIImageView; en su lugar se usa WKInterfaceImage. Y aquí tintColor funciona de manera diferente.
Enfoque correcto para WatchKit
// En InterfaceController.swift@IBOutlet weak var watchImage: WKInterfaceImage!
override func awake(withContext context: Any?) { super.awake(withContext: context) // Configuramos la imagen watchImage.setImage(UIImage(named: "watchIcon")) // Aplicamos el color watchImage.setTintColor(UIColor.green)}Importante: el método se llama setTintColor(_:), no simplemente tintColor. Y sí, la imagen debe estar en formato Template Image. En WatchKit, esto se hace a través del atributo Render As en el catálogo de assets.
Ejemplo práctico: creando un icono adaptable
Juntemos todo. Supongamos que tenemos una aplicación con cambio de tema oscuro y claro. El icono de configuración debe cambiar de color según el tema.
class SettingsView