The dark chip created by Dr.Regal trying to make powerful dark chips. In the anime Megaman didn't use it but got his data corrupted by shade man by biting him on the neck. Eventually he turns to the dark aide but when he mange to recover him self for a limit time he made shade man pay. NES - Mega Man - The #1 source for video game sprites on the internet!
Dark Mode was introduced in iOS 13 and announced at WWDC 2019. It adds a darker theme to iOS and allows you to do the same for your app. It’s a great addition to give to your users so they can experience your app in a darker design. Tiny and big: grandpa's leftovers for mac.
In this blog post, I’ll share with you my experiences after we’ve added Dark Mode support to the Collect by WeTransfer app.
Before we dive into the adoption of the Dark interface style I want to shortly tell you how you can opt-out. Once you start building your app using Xcode 11 you’ll notice that the darker appearance is enabled by default.
If you don’t have the time to add support for Dark mode you can simply disable it by adding the
UIUserInterfaceStyle to your
Info.plist and set it to
You can override the user interface style per view controller and set it to light or dark using the following code:
You can do the same for a single
Overriding the user interface style per window can be handy if you want to disable Dark Mode programmatically:
Note that we’re making use of the windows array here as the
keyWindow property on the shared
UIApplication is deprecated starting from iOS 13. It’s discouraged to use it as applications can now support multiple scenes that all have an attached window.
If you start implementing a darker appearance in your app it’s important to have a good way of testing. There are multiple ways to enable and switch appearance mode that all have their benefits.
Navigate to the Developer page in the Settings app on your simulator and turn on the switch for Dark Appearance:
On a device, you can enable Dark Mode by navigating to the Display & Brightness page in the Settings app. However, it’s a lot easier during development to add an option to the Control Centre to quickly switch between dark and light mode:
While working in Xcode with the simulator open you might want to use the Environment Overrides window instead. This allows you to quickly switch appearance while debugging:
Note: If you don’t see this option you might be running on an iOS 12 or lower device.
While working on your views inside a Storyboard it can be useful to set the appearance to dark inside the Storyboard. You can find this option next to the device selection in the bottom:
The previous section covered the enabling and disabling of Light Mode throughout the whole app using the
Info.plist or disabling it per view, view controller or window. This is a great way if you temporary want to force the Dark appearance for testing purposes.
With Dark Mode on iOS 13, Apple also introduced adaptive and semantic colors. These colors adjust automatically based on several influences like being in a modal presentation or not.
Adaptive colors automatically adapt to the current appearance. An adaptive color returns a different value for different interface styles and can also be influenced by presentation styles like a modal presentation style in a sheet.
Semantic colors describe their intentions and are adaptive as well. An example is the
label semantic color which should be used for labels. Simple, isn’t it?
When you use them for their intended purpose, they will render correctly for the current appearance. The
label example will automatically change the text color to black for light mode and white for dark.
It’s best to explore all available colors and make use of the ones you really need.
If possible, it will be a lot easier to adopt Dark Mode if you’re able to implement semantic and adaptive colors in your project. For this, I would highly recommend the SemanticUI app by Aaron Brethorst which allows you to see an overview of all available colors in both appearances.
As soon as you start using semantic colors you will realize that they only support iOS 13 and up. To solve this we can create our own custom UIColor wrapper 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.
Another benefit of this approach is that you’ll be able to define your own custom Style object. This allows theming but also makes your color usage throughout the app more consistent when forced to use this new Style configuration.
A custom semantic color can be created by using the earlier explained
UIColor.init(dynamicProvider: @escaping (UITraitCollection) -> UIColor) method.
Often times, your app has its own identical tint color. It could be that this color works great in Light mode but less in Dark. For that, you can return a different color based on the current interface style.
Dark mode can be detected by using the
userInterfaceStyle property on the current trait collection. When it’s set to
dark you know that the current appearance is set to dark.
When you use adaptive colors with CALayers you’ll notice that these colors are not updating when switching appearance live in the app. You can solve this by making use of the
Once you’re done with updating all the colors it’s time to update the assets in your app.
The easiest way to do this is by using an Image Asset Catalog. You can add an extra image per appearance.
This makes your image adaptive as well and adjust the image accordingly for the current interface style.
It’s not always the best option to add extra assets for each appearance. In the end, it makes your app size bigger.
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 and tab bars.
First, you need to make the asset render as template:
You could do the same in code:
After that, you can simply set the image view tint color to make the icon adjust its color based on the current appearance:
Inverting colors can be another way to save app size. This does not always work for each image but can be a solution that prevents you from adding another asset to your bundle.
You can do this by making use of the following
You need to update your image manually when the appearance is updated. Therefore, it’s recommended to use the method as follows:
In some cases, you want to define two colors inline for both light and dark mode. Custom operators can help us do this relatively simple:
This custom operator allows us to define a dynamic color that adopts automatically as follows:
We covered a lot of tips for adapting Dark Mode in your app. We also explained the benefits of using Semantic and Adaptive Colors. Hopefully, this helped you to implement Dark Mode a bit more efficient!
As you’re busy working with assets, either way, you might want to clean up your unused assets directly as well! If you like to improve your Swift knowledge, even more, check out the Swift category page. Feel free to contact me or tweet to me on Twitter if you have any additional tips or feedback.