Pourquoi les icônes ne veulent-elles pas changer de couleur ? Découverte de tintColor
Imaginez : vous développez une application pour iPhone ou Apple Watch. Le designer vous a envoyé un bel ensemble d'icônes noires. Vous les placez dans un UIImageView, vous appliquez tintColor — et… rien ne se passe. L'icône reste noire, comme avant. Cela vous dit quelque chose ? Cette question est l'une des plus fréquentes sur Stack Overflow, et aujourd'hui nous allons l'analyser en profondeur.
Le problème est que tintColor fonctionne uniquement avec les images qui sont en mode Template Image. Si vous définissez simplement une couleur pour une image normale (Original Image), le système ignorera votre demande. Apprenons à maîtriser ce mécanisme.
Qu'est-ce qu'une Template Image et pourquoi en a-t-on besoin ?
Dans iOS et WatchKit, toutes les images sont divisées en deux types :
- Original Image — une image normale avec toutes ses couleurs. Elle ne peut pas être colorée via
tintColor. - Template Image — une image où seule la transparence (canal alpha) est prise en compte comme couleur. Tous les pixels visibles deviennent « vides » — ils sont prêts à accepter n'importe quelle couleur que vous définissez.
Lorsque vous appliquez tintColor à une Template Image, le système remplit toutes les zones opaques avec la couleur spécifiée. C'est idéal pour les icônes, les boutons et les éléments d'interface qui doivent s'adapter au thème de l'application.
Méthodes pour modifier tintColor dans iOS (Swift)
1. La méthode la plus simple : via Interface Builder
Si vous travaillez dans Storyboard ou XIB :
- Sélectionnez votre
UIImageViewouUIButton. - Dans l'inspecteur d'attributs, trouvez le champ Render Mode.
- Définissez-le sur Template Image.
- Maintenant, la propriété Tint dans l'inspecteur fonctionnera.
2. Méthode programmatique : code en Swift
Voici comment procéder correctement :
// Charger l'imagelet originalImage = UIImage(named: "myIcon")
// Convertir en Templatelet templateImage = originalImage?.withRenderingMode(.alwaysTemplate)
// Appliquer à UIImageViewimageView.image = templateImageimageView.tintColor = UIColor.systemBlueLa méthode clé est withRenderingMode(.alwaysTemplate). Elle indique au système : « Ne tiens pas compte des couleurs d'origine, je vais tout colorer moi-même ».
3. Changer la couleur pour UIButton
Pour les boutons, le processus est similaire, mais avec une nuance :
button.setImage(UIImage(named: "heart")?.withRenderingMode(.alwaysTemplate), for: .normal)button.tintColor = UIColor.redRemarque : nous appliquons withRenderingMode directement à l'image que nous définissons pour le bouton.
Particularités de tintColor dans WatchKit
Le développement pour Apple Watch a ses propres limites. Dans WatchKit, il n'y a pas de UIImageView — on utilise WKInterfaceImage à la place. Et ici, tintColor fonctionne différemment.
Approche correcte pour WatchKit
// Dans InterfaceController.swift@IBOutlet weak var watchImage: WKInterfaceImage!
override func awake(withContext context: Any?) { super.awake(withContext: context) // Définir l'image watchImage.setImage(UIImage(named: "watchIcon")) // Appliquer la couleur watchImage.setTintColor(UIColor.green)}Important : la méthode s'appelle setTintColor(_:), et non simplement tintColor. Et oui, l'image doit être au format Template Image. Dans WatchKit, cela se fait via l'attribut Render As dans le catalogue d'assets.
Exemple pratique : créer une icône adaptative
Rassemblons tout cela. Supposons que nous ayons une application avec un basculement entre le thème sombre et le thème clair. L'icône des paramètres doit changer de couleur en fonction du thème.
class SettingsView