Dark Mode, Dark Theme: Adding Support to Your Application

The dark side is on the march this autumn. Both iOS 13 and Android 10 are introducing the setting to opt into the dark version of the interface on the mobile phone. It saves battery life, reduces digital eye strain and makes the Dark Lord happy. System applications obviously support it out of the box, but third-party app developers don't get the dark support for free. Certain steps need to be taken and code written in order to add the support for this shiny (or actually the opposite of "shiny") new feature.

iOS

Dark Mode colors will be imposed by iOS to any application that is linked against iOS 13 or later SDK and doesn't explicitly opt-out by including UIUserInterfaceStyle key (with a value of Light) in the Info.plist file. If your application only uses system colors and Ui is not built around the images, it may work right away. But most likely your application has a heavily customized UI with the colors, handpicked by your designer. Best case - it will look exactly the same in both dark and light mode, worst case - it will look crappy in a dark mode.

Most likely you will need to define a different color palette for the dark mode. You can utilize asset catalogs and create named colors, which can have different version for dark and light mode. Same can be done for images.

So if you have everything in assets catalogs, chances are you can customize the application by simply editing those without writing a single line of code. If you do not, it is a good time to move everything there.

If you need to detect the presence of the dark mode programmatically, you can query the userInterfaceStyle of UIViewController's traitCollection.

if traitCollection.userInterfaceStyle == .light {
    print("Light mode")
} else {
    print("Dark mode")
}

All the details and further information can be found in the official Apple guide.

Android

Unlike iOS, Android Q dark theme support is only enabled if opted-in by the developer. They also provide an easy way to turn that support on. Just add android:forceDarkAllowed to your styles.xml with:

<style name=”AppTheme” parent=”Theme.AppCompat.Light”>
    <item name=”android:forceDarkAllowed”>true</item>
</style>

This basically instructs Android OS to change application colors to a dark theme, making guesses about what those colors should be. In the simple cases that looks impressive.

On the actual cases in your application, it might not be the case. The second option is to actually customize your application colors manually. Good news - you can combine both approaches within the same application: some screens can be "force dark" and some can use a manually set dark palette. This way developers can balance polished look and time spent.

Android documentation actually gives a good starting point on how to achieve that specifically. Also, I recommend this article for insights and details on Android dark theme.

React Native

React Native provides the view rendering system that is platform-independent and not tied to any specific iOS. Approaches described above are of no use to React Native views. You render everything in your code and you have full control of what is rendered.

When building React Native application it is always a good idea to have some support for an application theme. If your application uses one of the major UI frameworks like: native-basereact-native-ui-kitten or react-native-elements - the theming is included and you should consult the framework's documentation on how to utilize that.

If you do not have any support for theming in your React Native application - you are in trouble. You have 2 choices: either add that support or make the code even less maintainable by introducing ifs here and there.

Detecting the dark mode/theme was not finalized in the most recent React Native release at the time of writing. However, a third-party package exists.

Vitaliy Ivanov Technical Director at Factorial Complexity