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?
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]