How to Implement Light and Dark Theme Using Xcode

Ivan Štajcer
4 min readMar 13, 2022

You’re trying to create different looks for your app based on a light or dark theme?

So stop looking for different ways to code or libraries that will satisfy your needs — your pal, Xcode has got you covered.

In this article, I will show you how to provide colors and images for a light and dark theme using Xcode Best of all, you won’t have to write any theme-specific code, you’ll just use the assets folder. I will however show you how to get the current theme in code and how to listen to the theme changes.

Code for this application can be found on my GitHub repository: https://github.com/igniti0n/theming_with_Xcode.git

Colors

When you add a new color set to your assets folder, by default you can give one universal color value to it. You can change the properties of that set by going to its attributes inspector. In there you will see the appearance property.

Appearance property

A color set can have different values for a certain appearance and can have, at most, three different ones: any, light, and dark appearance. You can select variations based on those three.

Choose the ‘Any, Light, Dark’ option. You should see three empty slots, each representing one appearance. Fill them out with the color of your choosing. From now on, when you use this color set, your application chooses the color based on the current system theme.

Here is an example of using the three mentioned appearances. See how the colors change by changing the system theme.

Colors change

You can change other properties in the attribute inspector. Selecting the ’High Contrast’ checkbox for example, will give you other color slots for high and normal contrast appearance.

Images

An image set can use different appearances the same way as a color set does, including high contrast images or images specific to a device.

Create a new image set and select the ‘Any, Dark’ appearance. Afterward, fill the empty slots with some images. See the example below.

Image appearances

Keep in mind that providing separate images for a light and dark mode increases your application size, which is something you want to avoid. If your image stays the same and only changes its color, you can avoid this by providing a tint color to the image. To do that, let’s see how to access the current theme and listen to theme changes.

Theme changes and tintable images

You can access the current theme through the ‘traitCollection’ property of classes that conform to the ‘UITraitEnvironment’ protocol, like UIView or UIViewController. This contains the ‘userInterfaceStyle’ property that tells us what is the current theme.

traitCollection.userInterfaceStyle == .light ? “light” : “dark”

This property changes though, so to keep track of when does it change you can override the ‘traitCollectionDidChange’ method and then update your views based on the current theme.

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {// Do some updates
mainView.updateView(with: traitCollection.userInterfaceStyle)
}

This is useful for the previously mentioned images that use tint color. To use a tinted image, make an image with its rendering mode as ‘always template’.

tintedImageView.image = UIImage(named:“icon”)?.withRenderingMode(.alwaysTemplate)                      

And then, adjust its tint color as you wish, your image will be overlayed with that color. This is very useful for single-colored images like icons.

func updateView(with theme: UIUserInterfaceStyle) {tintedImageView.tintColor = theme == .light ? .orange : .blue}
Image with tint color

Conclusion

This is more than enough for an application that wants to use a light or dark mode and only changes colors and images. No need for overcomplicating when an easy solution can satisfy your needs. Having to force an application to use light, dark, or system default, however, is another story.

I have published a library that solves this problem, while also allowing you to theme whole views, not just colors and images. You can check it out: https://github.com/igniti0n/Themer.

That is it for this article, clap 👏 If this article helped you in any way, and feel free to leave comments, questions, and improvements.

--

--

Ivan Štajcer

I am a mobile application developer mostly using Flutter and Swift