I have a navigation app. During a navigation session, I prevent the screen from sleeping. When users are driving/navigating around sunrise or sunset, appearance should change between light and dark mode.

In order to do this, I created a subclass of UIWindow:

class WindowWithDarkModeMonitor: UIWindow {

    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        super.traitCollectionDidChange(previousTraitCollection)
        print("traitCollectionDidChange")
    }

}

traitCollectionDidChange is supposed to be called whenever traits (like portrait/landscape and dark/light mode change). (Apple Documentation (b.t.w. I know this method will be deprecated, but my app needs to support iOS16 for the moment, so I still need it).

Now, the problem is, traitCollectionDidChange is not called on a scheduled appearance change. It IS called when I switch between dark and light mode through the control center. It's also called when I rotate my device.

I browsed a LOT, and have tried a LOT, but can't find a solution. This SO question comes close, but the top (and only) answer doesn't work for my case either.

After some testing, I actually found out that no app I know of changes from dark to light or vice versa when it's active in the foreground at the time of the scheduled change. You can try this yourself:

  • Go to iOS Settings > Display & Brightness
  • Set appearance to AUTOMATIC and for Options choose 'Custom Schedule' and choose the times so that a change is 1 or 2 minutes away.
  • Now open Apple Mail, or Safari, or any other app that supports dark mode
  • Make sure your display doesn't go to sleep, and wait until the minute passes where the dark/light switch should take place.
  • Nothing happens!!!
  • The dark/light switch is only applied after your iPhone is auto-locked or locked manually, and unlocked again.

I have a very strong feeling this is either an iOS bug (or a 'feature'?). In any case, it would be unfortunate for an app like mine, if I couldn't use the system's automatic dark/light switch at sunset/sunrise. I would have to build my own solution to determine if it's day or night (based on location and time zone). Not impossible, but I'd rather not re-invent the wheel, and keep my app as close to system behavior as possible.

So, is there any way to make the system call traitCollectionDidChange upon a scheduled appearance change (dark/light mode change)? Or, any other way to get notified about this?

0

There are 0 answers