traitCollectionDidChange deprecated in Xcode 15

I am using UIViewController, and I need to know when devices appearance changes. Previously this worked with a delegate function.

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection) // ⚠️
    // Update UI
}

Xcode 15 gives us the deprecation warning.

'traitCollectionDidChange' was deprecated in iOS 17.0: Use the trait change registration APIs declared in the UITraitChangeObservable protocol

The new function with the completion block registerForTraitChanges, needs the [UITrait] parameter.

Both of my attempts are failing to compile.

let traits = [UIUserInterfaceStyle.light, UIUserInterfaceStyle.dark]
view.registerForTraitChanges(traits) { _, _ in
    // Update UI
}

Cannot convert value of type '[UIUserInterfaceStyle]' to expected argument type '[UITrait]' (aka 'Array<any UITraitDefinition.Type>')

view.registerForTraitChanges(self.traitCollection.userInterfaceStyle) { _, _ in
    // Update UI
}

Cannot convert the value of type 'UIUserInterfaceStyle' to expected argument type '[UITrait]' (aka 'Array<any UITraitDefinition.Type>')

Please share working code example.
Also, does the completion block guarantee to run on the main thread?

Accepted Reply

Look closely at the code example under Discussion in the documentation for registerForTraitChanges(_:handler:). Note that you need to specify the UITrait type(s) that represent the trait(s) you are interested in, which would be expressed like this:

let traits = [UITraitUserInterfaceStyle.self]

Replies

Look closely at the code example under Discussion in the documentation for registerForTraitChanges(_:handler:). Note that you need to specify the UITrait type(s) that represent the trait(s) you are interested in, which would be expressed like this:

let traits = [UITraitUserInterfaceStyle.self]