Darkmode and multiwindows / scenes

Hello,

i'm trying to implement ios13 darkmode within multi scene application.

Unfortunately when i dismiss a scene dragging it over the screen edge the method traitCollectionDidChange is called several times with always different values, causing my UI to flicker between dark and light mode.


What's wrong?


Here is my implementation


func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)

    print("THEME instance: \(self)")

    let currentTraitCollection = self.traitCollection
    var hasUserInterfaceStyleChanged = false
    hasUserInterfaceStyleChanged = previousTraitCollection.hasDifferentColorAppearanceCompared(to: currentTraitCollection)
    
    print("THEME hasUserInterfaceStyleChanged = \(hasUserInterfaceStyleChanged ? "YES" : "NO")")
    
    if hasUserInterfaceStyleChanged {
        let userInterfaceStyle = currentTraitCollection.userInterfaceStyle // Either .unspecified, .light, or .dark
        
        switch userInterfaceStyle {
            case .unspecified:
                print("THEME UIUserInterfaceStyleUnspecified")
            case .light:
                print("THEME UIUserInterfaceStyleLight")
            case .dark:
                print("THEME UIUserInterfaceStyleDark")
            }
    } else {
        print("THEME NOT CHANGED")
    }
    
}

Here is the logged statements in console


Whene new scene comes in...

THEME instance: <MainControllerViewController: 0x117e55910>
THEME hasUserInterfaceStyleChanged = YES
THEME UIUserInterfaceStyleLight


Whene added scene goes away...


THEME instance: <MainControllerViewController: 0x117e55910>
THEME hasUserInterfaceStyleChanged = YES
THEME UIUserInterfaceStyleDark
THEME instance: <MainControllerViewController: 0x117e55910>
THEME hasUserInterfaceStyleChanged = YES
THEME UIUserInterfaceStyleLight
THEME instance: <MainControllerViewController: 0x117e55910>
THEME hasUserInterfaceStyleChanged = NO
THEME NOT CHANGED
THEME instance: <MainControllerViewController: 0x117e55910>
THEME hasUserInterfaceStyleChanged = YES
THEME UIUserInterfaceStyleDark
THEME instance: <MainControllerViewController: 0x117e55910>
THEME hasUserInterfaceStyleChanged = YES
THEME UIUserInterfaceStyleLight


in meantime i have no changed to dark mode (always light)...so i expect just THEME NOT CHANGED.

Replies

This might be related to the snapshot images that iOS takes when an app (and now scene) disappears. In previous iOS versions I have seen a fake rotation to landscape/portrait and back again on iPad. I read on Twitter that iOS 13 also fakes an appearance change so that, presumably, it can have snapshot images ready to show your app in the the task switcher in the future if it doesn't get a chance to run again. It takes both light and dark versions in case the user changes appearance between your app disappearing and iOS needing to show your UI in the task switcher. The other change you see that doesn't seem to change the appearance is probably a landscape/portrait rotation if you are on iPad.


But I wouldn't expect you to see (with your eyes) that happening, because the app/scene is no longer on screen when iOS takes the snapshot images.

Amazing intuition!

I see them because i need to "manually update" some UI components when trait changes from light to dark.


How can i distinguish between the scene going away and let the system do its job and the scene which is still on foreground?

Of course when the user intentionally changes to dark mode, both must react accordingly.

I'm seeing pretty much the same thing ... Did you ever solve the issue of the unwanted flickering between light and dark mode?


Thanks!

I was seeing pretty much the same thing but it had to with the mechanism I was using to update my UI. The extra call(s) made by iPadOS to capture screens in light and dark mode should usually be transparent to the user. Just be careful with what you're actually doing when the userInterfaceStyle changes. Improper tasks can lead to flickering of light and dark mode. I was suffering from that problem because I was using notification pattern to update multiple viewControllers. Doing something more direct corrected the problem my specific issue.


Good luck!