Changing icon colors in iOS and WatchKit: tintColor for beginners

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Why don't icons want to change color? Introduction to tintColor



Imagine: you're writing an app for iPhone or Apple Watch. The designer sent a beautiful set of black icons. You place them in a UIImageView, apply tintColor — and… nothing happens. The icon remains black as before. Sound familiar? This question is one of the most common on Stack Overflow, and today we'll break it down at the molecular level.



The problem is that tintColor only works with images that are in Template Image mode. If you simply set a color for a regular image (Original Image), the system will ignore your request. Let's learn how to control this mechanism.



What is a Template Image and why is it needed?



In iOS and WatchKit, all images are divided into two types:

  • Original Image — a regular image with all its colors. It cannot be colored via tintColor.
  • Template Image — an image where only the alpha channel (transparency) is considered color. All visible pixels become "empty" — they are ready to accept any color you specify.


When you apply tintColor to a Template Image, the system fills all opaque areas with the specified color. This is ideal for icons, buttons, and interface elements that should adapt to the app's theme.



Ways to change tintColor in iOS (Swift)



1. The simplest way: via Interface Builder

If you're working in Storyboard or XIB:

  1. Select your UIImageView or UIButton.
  2. In the Attributes Inspector, find the Render Mode field.
  3. Set it to Template Image.
  4. Now the Tint property in the inspector will work.


2. Programmatic way: Swift code

Here's how to do it correctly:



// Load the imagelet originalImage = UIImage(named: "myIcon")

// Convert to Templatelet templateImage = originalImage?.withRenderingMode(.alwaysTemplate)

// Apply to UIImageViewimageView.image = templateImageimageView.tintColor = UIColor.systemBlue


The key method is withRenderingMode(.alwaysTemplate). It tells the system: "Ignore the original colors, I'll paint everything myself."



3. Changing color for UIButton

For buttons, the process is similar, but there's a nuance:



button.setImage(UIImage(named: "heart")?.withRenderingMode(.alwaysTemplate), for: .normal)button.tintColor = UIColor.red


Note: we apply withRenderingMode directly to the image we set for the button.



tintColor specifics in WatchKit

Apple Watch development has its limitations. In WatchKit, there is no UIImageView — instead, WKInterfaceImage is used. And here, tintColor works differently.



The correct approach for WatchKit

// In InterfaceController.swift@IBOutlet weak var watchImage: WKInterfaceImage!

override func awake(withContext context: Any?) { super.awake(withContext: context) // Set the image watchImage.setImage(UIImage(named: "watchIcon")) // Apply the color watchImage.setTintColor(UIColor.green)}


Important: the method is called setTintColor(_:), not just tintColor. And yes, the image must be in Template Image format. In WatchKit, this is done via the Render As attribute in the asset catalog.



Practical example: creating an adaptive icon

Let's put it all together. Suppose we have an app with dark and light theme switching. The settings icon should change color depending on the theme.



class SettingsView                

Blogs

Book Recommendations