1

I have implemented dark mode in my iOS app, and while it works, the changes don't occur immediately. I think this has to do with the views not recreating themselves all the time like they do in android.

For instance, it doesn't work to go out from the app, then to settings and change theme, then back in the app again. The changes have only then occurred to Apple-related framework like alertControllers. To get dark mode to work I have to click around to a new view, then go back to the old view again.

I have tried adding dark mode code in the delegate, as I thought this would run every time you reenter your app, but it didn't.

So, any ideas on how to make this work? Is there for instance a delegate that is run every time I reenter the app, or can I have an observer to dark mode changes?

Blazej SLEBODA
  • 8,936
  • 7
  • 53
  • 93

2 Answers2

5

You could implement this method to "listen" to TraitCollection changes:

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
    // do whatever you want to do 
}

Also, as Gergely mentioned, try to use xcassets for colors and images so they dynamically change depending on the current TraitCollection.

Teetz
  • 3,475
  • 3
  • 21
  • 34
  • Can I use this in the delegate so I only need to implement it once, or do I need to have this code in every single view? – screenMonkey MonkeyMan Dec 06 '19 at 09:12
  • This really depends on your needs i guess. If you use the xcassets i think there are only a few things that need to adapt manually. Or you figure out a smart way to implement this for all Controllers (like adding a BaseViewController etc.) – Teetz Dec 06 '19 at 09:14
  • You don't need to use this at all if you just use image/color assets instead of hard coding them. Very easy and intuitive approach that makes your app respond nicely to screen changes, – Gergely Kovacs Dec 06 '19 at 09:19
  • @GergelyKovacs This is not always possible i think. For example we are using a GoogleMap in our app with custom styles for light and dark mode. For this Use Case for example we need to apply a new mapStyle when the TraitCollection changes. But for most cases you are right I think. – Teetz Dec 06 '19 at 09:28
  • @Teetz You are right; there are rare cases when you need this. I had to use traitCollectionDidChange as well because I use CALayers in some places which do not update dynamically. But for the majority of cases, the whole dark mode support can be done with simple color/image assets without writing a single line of code. – Gergely Kovacs Dec 06 '19 at 09:34
  • @Teetz, thank you for your help, that was much needed! Really appreciate it :) – screenMonkey MonkeyMan Dec 06 '19 at 10:05
  • @screenMonkeyMonkeyMan glad i could help :) – Teetz Dec 06 '19 at 10:05
  • @GregelyKovacs I think I'm one of those rare cases where assets won't go all the way :) – screenMonkey MonkeyMan Dec 06 '19 at 10:07
1

Alert view controllers update because they use responsive system colors for their text and background, which have versions for both light and dark mode by default and update automatically once the mode changes.

You can do the same with custom views if you use color and image assets. this is a nice overview of how to do things: Medium Article.

The official Apple documentation also has a nice overview of how to support dark mode: Supporting Dark Mode in Your Interface.

Gergely Kovacs
  • 1,045
  • 2
  • 10
  • 28