Dark Mode in iOS : Detailing every thing from start to end (Swift)

Varun Tomar
6 min readOct 20, 2020

This post may seem quite late as dark mode was introduced in iOS 13. Nevertheless i want to put all details in a single article that you may require to allow your app users to experience dark mode. We are going to explore below points step by step :

  1. Opt-in and Opt-out dark mode in your app
  2. Overriding dark mode per view and view controller
  3. Semantic Colors
  4. System Colours
  5. Blur and Vibrancy effect
  6. SF Symbols
  7. Updating images and colours for dark mode
  8. Invert colours of an image to support dark mode
  9. Dark mode support in WKWebView
  10. Dark mode behaviour testing

Lets move into dark like a batman 🦇 🦇

Opt-in and Opt-out dark mode in your app

The very first thing when you start building your app using Xcode 11 onwards the darker appearance is enabled by default. If you don’t want to add support for Dark mode you can simply disable it by adding the UIUserInterfaceStyle to your Info.plist and set it to Light.

Overriding dark mode per view and view controller

You can override the user interface style per view controller/view/window and set it to light or dark using the following code:

Semantic Colors

With Dark Mode on iOS 13, Apple also introduced adaptive and semantic colors. These colors do not have absolute RGB value, they automatically adapt to the iOS interface style (light mode/dark mode). According to Apple documentation, we should use semantic colors whenever it is possible so that our app will be future-proof with any UI changes made by Apple.

I would highly recommend the SemanticUI app by Aaron Brethorst which allows you to see an overview of all available colors in both appearances.

SemanticUI app by Aaron helps exploring Semantic and adaptable colours

As semantic colors only support iOS 13 and above. To solve this problem we can use our own custom UIColor wrapper class by making use of the UIColor.init(dynamicProvider: @escaping (UITraitCollection) -> UIColor) method. This allows you to return a different color for iOS 12 and lower.

Or if you need to add your own semantic color, Dark mode can be detected by using the userInterfaceStyle property on the current trait collection. You can create this customise behaviour following way :

Create your custom semantic colour

NOTE : When you use adaptive colors with CALayers, they wont update when switching appearance live in the app. You can resolve this by making use of the traitCollectionDidChange(_:) method. From Apple Developer Documentation:

The system calls this method when the iOS interface environment changes. Implement this method in view controllers and views, according to your app’s need, to respond to such changes. For example, you might adjust the layout of the subviews of a view controller when an iPhone is rotated from portrait to landscape orientation. The default implementation of this method is empty.

System Colors

Apart from the semantic colors commonly used in iOS UI elements, Apple has also introduced 9 system colors with various variants. All these system colors are dynamic, meaning they will automatically adapt to the selected interface style just like semantic colors.

SemanticUI app by Aaron helps exploring System and adaptable colours

Blur and Vibrancy effect

iOS 13 onwards, Apple introduced 4 types of blur effects and 8 types of vibrancy effects. Interestingly all these visual effects will automatically adapt to iOS interface style. Please check following available blur effects : thick, regular, thin and ultrathin.

Blur in light and dark mode : Source : https://developer.apple.com/

Along with system blur, we also have 4 types of vibrancy effects for text (Labels), 3 types of vibrancy effect for overlay (Fills) and 1 specific vibrancy effect for separator.

Vibrancy in light and dark mode : Source : https://developer.apple.com/

SF Symbols

SF Symbols is a collection of over 2,400 symbols provided by Apple to use within apps. As mentioned in iOS Human Interface Guidelines, SF Symbols automatically look perfect in Dark Mode and they are optimised for both light and dark appearances. SF symbols are highly customisable, there are 3 sizes and 9 weight levels for every symbol to choose from. Moreover, you can also change the SF Symbols tint color base on your app’s requirements.

Source : https://developer.apple.com/

Apple highly recommend developers to use SF Symbols if possible.

Updating images and colors for dark mode

The easiest way to do this is by using an Image Asset Catalog. You can add an extra image or color per appearance.

In a same way as above we can add different images for light and dark mode. But it’s not always the best bet to add extra assets for both appearance. It makes your app bigger in size. Therefore, a good alternative is to look for images that can be used with a tint color. This especially works great with icons that are used in, for example, toolbars. To make use of tint color on images, you need to make the asset render as template:

Invert colors of an image to support dark mode

Inverting colors of an image can be another way to avoid separate image for light and dark mode. This doesn’t always work for each image but can be a solution that prevents you from increasing app size. You can use following UIImage extension to invert colours:

NOTE : You need to update your image manually when the appearance is updated. Therefore, it’s recommended to use the method as follows:

Below is the result when we apply this :

Dark mode support in WKWebView

When you need to use a WKWebView to show content in your App, generally you load it from a remote web server. So at client end. you can’t do much to make it support in dark mode. I am going to explain how we can do it on our web server but if you use local HTML content in your app even then the process also remains same.

By default WebKit does NOT automatically darken web content. You opt-in using the color-scheme property on the root element in your CSS stylesheet:

You just need to create variable for the colour and need to handle this in CSS as following:

Lets walk through above code as per comments mentioned :

  1. We opt-in using the color-scheme property on the root element in our CSS stylesheet
  2. We have to replace all hard-coded colors in the CSS file with CSS variables. This will make it easier to override the colors for the dark color scheme.
  3. Using a media query we can now override the color variables for the dark color scheme.
  4. We replaced hard coded colors with variables.

For images also we can improve things with a dark mode variation of the image. Instead of modifying the CSS we use a picture element with a media query in the HTML as follows:

For more details i recommend to visit https://developer.apple.com/videos/play/wwdc2019/511/

Dark Mode Testing in Xcode

It’s last but not least. Although you may know how to test dark mode behaviour but i just want to cover if somebody doesn’t.

  1. Navigate to the Developer page in the Settings app on the simulator and turn on the switch for Dark Appearance.
  2. 2. If you want to quickly switch appearance while debugging. In Xcode with the simulator open you can use the Environment Overrides window instead:

3. In Storyboard also it can be useful to set the appearance to dark. You can find this option next to the device selection in the bottom:

Hope you enjoyed this article. If you feel, please share and give some claps 👏👏 and stay tuned 😄😄 for next articles. Thanks for reading this🙏🙏. Any feedback in the comment section would be highly appreciated.

You can follow me for fresh articles.

--

--