How to detect Light\Dark mode change in iOS 13?

I think this should get called significantly less often, plus the guard makes sure you only react to user interface style changes:

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

    guard previousTraitCollection?.userInterfaceStyle != traitCollection.userInterfaceStyle else {
        return
    }
    dropShadowIfNeeded()
}

SwiftUI

With a simple environment variable on the \.colorScheme key:

struct ContentView: View {
    @Environment(\.colorScheme) var colorScheme

    var body: some View {
        Text(colorScheme == .dark ? "Its Dark" : "Its. not dark! (Light)")
    }
}

UIKit

As it described in WWDC 2019 - Session 214 around 23:30.

As I expected, this function is getting called a lot including when colors changing. Along side with many other functions for ViewController and presentationController. But there is some especial function designed for that has a similar signature in all View representers.

Take a look at this image from that session:

WWDC 2019 - Session 214

Gray: Calling but not good for my issue, Green: Designed for this

So I should call it and check it inside this function:

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)
    
    if traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {
        dropShadowIfNeeded()
    }
}

This will guarantee to be called just once per change.

if you are only looking for the initial state of the style, check out this answer here